Files
rick-infra/docs/sigvild-gallery-deployment.md
Joakim ecbeb07ba2 Migrate sigvild-gallery to production environment
- Add multi-environment architecture (homelab + production)
- Create production environment (mini-vps) for client projects
- Create homelab playbook for arch-vps services
- Create production playbook for mini-vps services
- Move sigvild-gallery from homelab to production
- Restructure variables: group_vars/production + host_vars/arch-vps
- Add backup-sigvild.yml playbook with auto-restore functionality
- Fix restore logic to check for data before creating directories
- Add manual variable loading workaround for Ansible 2.20
- Update all documentation for multi-environment setup
- Add ADR-007 documenting multi-environment architecture decision
2025-12-15 16:33:33 +01:00

8.2 KiB

Sigvild Gallery Deployment Guide

Overview

Sigvild Wedding Gallery is deployed on mini-vps (production environment) for high uptime and reliability. The gallery uses PocketBase API backend with SvelteKit frontend.

Production Host: mini-vps (72.62.91.251)
Domains: sigvild.no (frontend), api.sigvild.no (API)

Quick Start

Deploy Sigvild Gallery to production:

ansible-playbook playbooks/production.yml

Prerequisites Setup

1. Vault Password Configuration

Encrypted passwords are stored in group_vars/production/vault.yml:

# Edit production vault (run from rick-infra directory)
ansible-vault edit group_vars/production/vault.yml

Add these variables:

# Production vault variables
vault_cloudflare_api_token: "your-cloudflare-token"
vault_caddy_tls_email: "admin@example.com"
vault_sigvild_host_password: "host-user-password"
vault_sigvild_guest_password: "guest-user-password"
vault_pb_su_email: "admin@sigvild.no"
vault_pb_su_password: "admin-password"

Note: Use ansible-vault encrypt group_vars/production/vault.yml after editing.

2. DNS Configuration

Point these domains to mini-vps (72.62.91.251):

  • sigvild.no A record → 72.62.91.251
  • api.sigvild.no A record → 72.62.91.251

3. Project Structure

Ensure the sigvild-gallery project is adjacent to rick-infra:

~/
├── rick-infra/          # This repository
└── sigvild-gallery/     # Sigvild gallery project
    ├── build_tmp/       # Production builds
    ├── sigvild-kit/     # Frontend source
    └── main.go          # Backend source

Deployment Commands

Production Deployment

Deploy to production environment (mini-vps):

# Deploy complete production stack (Caddy + Sigvild Gallery)
ansible-playbook playbooks/production.yml

# Or deploy everything with production limit
ansible-playbook site.yml -l production

Selective Updates

Update specific components using tags:

# Frontend only (quick static file updates)
ansible-playbook playbooks/production.yml --tags="frontend"

# Backend only (API service updates)  
ansible-playbook playbooks/production.yml --tags="backend"

# Caddy configuration only
ansible-playbook playbooks/production.yml --tags="caddy"

# Just build process (development)
ansible-playbook playbooks/production.yml --tags="build"

Backup and Restore

Create backups before major changes:

# Create backup (works on any host running sigvild-gallery)
ansible-playbook playbooks/backup-sigvild.yml -l mini-vps

# Backup is saved to: ~/sigvild-gallery-backup/

Automatic Restore: When deploying to a fresh server, the role automatically detects and restores from the latest backup if available.

Architecture Overview

Production Environment: mini-vps (72.62.91.251)

Internet
    ↓
Cloudflare DNS → mini-vps
    ↓
Caddy (Auto HTTPS with DNS Challenge)
    ├── sigvild.no → /var/www/sigvild-gallery/ (Static Files)
    └── api.sigvild.no → localhost:8090 (PocketBase API)
            ↓
        Go Binary (/opt/sigvild-gallery/sigvild-gallery)
            ↓
        SQLite Database (/opt/sigvild-gallery/pb_data/)
            └── File Storage (wedding photos)

Key Features:

  • Automatic HTTPS with Let's Encrypt
  • Cloudflare DNS challenge for certificate validation
  • Security headers and CORS protection
  • SystemD service management
  • Automatic backup/restore capability

Service Management

Status Checks

# Check services on mini-vps
ansible mini-vps -a "systemctl status sigvild-gallery"
ansible mini-vps -a "systemctl status caddy"

# View gallery logs
ansible mini-vps -a "journalctl -u sigvild-gallery -n 50 --no-pager"

# View Caddy logs
ansible mini-vps -a "journalctl -u caddy -n 20 --no-pager"

# Check data directory
ansible mini-vps -a "ls -lh /opt/sigvild-gallery/pb_data/"

Manual Operations

# Restart gallery service
systemctl restart sigvild-gallery

# Reload Caddy configuration
systemctl reload caddy

# Check API health
curl https://api.sigvild.no/api/health

Troubleshooting

Build Issues

Problem: Go build fails

# Ensure Go is installed locally
go version

# Check if you're in the right directory
ls sigvild-gallery/main.go

Problem: Frontend build fails

# Check Node.js and npm
node --version && npm --version

# Ensure dependencies are installed
cd sigvild-gallery/sigvild-kit
npm install

Service Issues

Problem: Service won't start

# Check service status
systemctl status sigvild-gallery

# Check service logs
journalctl -u sigvild-gallery --no-pager

# Verify binary permissions
ls -la /opt/sigvild-gallery/sigvild-gallery-server

Problem: Database permissions

# Check data directory ownership
ls -la /opt/sigvild-gallery/data/

# Fix ownership if needed
sudo chown -R sigvild:sigvild /opt/sigvild-gallery/

Network Issues

Problem: Domain not resolving

# Test DNS resolution
dig sigvild.no
dig api.sigvild.no

# Test local connectivity
curl -H "Host: sigvild.no" http://localhost
curl -H "Host: api.sigvild.no" http://localhost

Problem: HTTPS certificate issues

# Check Caddy logs for ACME errors
journalctl -u caddy | grep -i "acme\|certificate"

# Verify DNS challenge credentials
# (Check Cloudflare API token in vault)

Security Features

Environment Protection

  • No .env files: Secrets stored in systemd environment variables only
  • Vault encryption: All passwords encrypted with ansible-vault
  • Memory isolation: Secrets only exist in process memory

SystemD Sandboxing

  • Read-only filesystem: Application cannot modify system files
  • Isolated temporary: Private /tmp directory
  • Limited capabilities: No privilege escalation possible
  • Data directory only: Write access restricted to /opt/sigvild-gallery/data/

Web Security

  • Automatic HTTPS: Let's Encrypt certificates via DNS challenge
  • Security headers: XSS protection, frame options, content type sniffing prevention
  • CORS restrictions: API access limited to frontend domain
  • Rate limiting: API endpoint protection

File Locations (on mini-vps)

Application Files

  • Binary: /opt/sigvild-gallery/sigvild-gallery
  • Database: /opt/sigvild-gallery/pb_data/data.db
  • File uploads: /opt/sigvild-gallery/pb_data/storage/
  • Frontend: /var/www/sigvild-gallery/
  • User/Group: sigvild:sigvild

Configuration Files

  • Service: /etc/systemd/system/sigvild-gallery.service
  • Caddy frontend: /etc/caddy/sites-enabled/sigvild-frontend.caddy
  • Caddy API: /etc/caddy/sites-enabled/sigvild-api.caddy

Local Files (on control machine)

  • Configuration: group_vars/production/main.yml
  • Secrets: group_vars/production/vault.yml (encrypted)
  • Backups: ~/sigvild-gallery-backup/
  • Source code: ~/sigvild-gallery/

Log Files

  • Service logs: journalctl -u sigvild-gallery
  • Caddy logs: journalctl -u caddy
  • Access logs: /var/log/caddy/access.log

Next Steps After Deployment

  1. Verify services: Check that both domains are accessible
  2. Test authentication: Login with host/guest credentials
  3. Upload test photo: Verify file upload functionality
  4. Monitor logs: Watch for any errors in service logs
  5. Backup setup: Configure regular database backups

Development Workflow

For ongoing development:

# 1. Make changes to sigvild-gallery project
cd ~/sigvild-gallery

# 2. Test locally  
go run . serve &
cd sigvild-kit && npm run dev

# 3. Deploy updates to production
cd ~/rick-infra
ansible-playbook playbooks/production.yml --tags="sigvild"

Build Process:

  • Backend: Built locally with GOOS=linux GOARCH=amd64 go build
  • Frontend: Built locally with npm run build in sigvild-kit/
  • Assets transferred to mini-vps via Ansible
  • No build tools required on the server

Migration History

December 2025: Migrated from arch-vps (homelab) to mini-vps (production)

  • Reason: Client project requiring higher uptime reliability
  • Method: Backup from arch-vps, automatic restore to mini-vps
  • Downtime: ~5 minutes during DNS propagation
  • Previous host: arch-vps (69.62.119.31)
  • Current host: mini-vps (72.62.91.251)