# 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: ```bash ansible-playbook playbooks/production.yml ``` ## Prerequisites Setup ### 1. Vault Password Configuration Encrypted passwords are stored in `group_vars/production/vault.yml`: ```bash # Edit production vault (run from rick-infra directory) ansible-vault edit group_vars/production/vault.yml ``` Add these variables: ```yaml # 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): ```bash # 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: ```bash # 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: ```bash # 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 ```bash # 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 ```bash # 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 ```bash # Ensure Go is installed locally go version # Check if you're in the right directory ls sigvild-gallery/main.go ``` **Problem**: Frontend build fails ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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: ```bash # 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)