- 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
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.noA record → 72.62.91.251api.sigvild.noA 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
- Verify services: Check that both domains are accessible
- Test authentication: Login with host/guest credentials
- Upload test photo: Verify file upload functionality
- Monitor logs: Watch for any errors in service logs
- 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 buildin 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)