- Fix Unix timestamp conversion in restore.yml using proper strftime syntax - Add service existence check before stopping sigvild-gallery service - Fix systemd service template environment variable syntax error - Add proper error handling for fresh deployments where service doesn't exist yet Resolves service management failures during restoration on fresh VPS installations.
Sigvild Gallery Ansible Role
Deploys the Sigvild Wedding Gallery application with PocketBase API backend and SvelteKit frontend.
Architecture
- Backend: PocketBase-based Go application serving API on localhost:8090
- Frontend: SvelteKit static site served by Caddy
- Database: SQLite via PocketBase (file-based storage)
- Authentication: Shared password system (host/guest users)
- Domains:
sigvild.no→ Frontend static filesapi.sigvild.no→ Backend API proxy
Prerequisites
- Caddy role deployed and configured
- Local sigvild-gallery project with built assets in
build_tmp/ - Vault-encrypted passwords configured in inventory
Variables
Required Variables
# Domains
sigvild_gallery_frontend_domain: "sigvild.no"
sigvild_gallery_api_domain: "api.sigvild.no"
# Vault-encrypted passwords
vault_sigvild_host_password: "your-encrypted-host-password"
vault_sigvild_guest_password: "your-encrypted-guest-password"
Optional Variables
# Service configuration
sigvild_gallery_user: "sigvild"
sigvild_gallery_port: 8090
sigvild_gallery_host: "127.0.0.1"
# Paths
sigvild_gallery_home: "/opt/sigvild-gallery"
sigvild_gallery_web_root: "/var/www/sigvild-gallery"
sigvild_gallery_local_project_path: "{{ ansible_env.PWD }}/sigvild-gallery"
# Backup configuration
sigvild_gallery_backup_enabled: true
sigvild_gallery_backup_local_path: "{{ playbook_dir }}/backups/sigvild-gallery"
Usage
Full Deployment
# Deploy complete infrastructure including Sigvild Gallery
ansible-playbook site.yml
# Deploy just Sigvild Gallery
ansible-playbook playbooks/deploy-sigvild.yml
Selective Updates
# Update just the frontend
ansible-playbook site.yml --tags="frontend"
# Update just the backend API
ansible-playbook site.yml --tags="backend"
# Update Caddy configuration
ansible-playbook site.yml --tags="caddy"
Data Backup and Restoration
Creating a Backup
Before formatting your server or making major changes, create a backup of all production data:
# Create backup of production data
ansible-playbook playbooks/backup-sigvild.yml
# Backup will be saved to: ./backups/sigvild-gallery/sigvild-gallery-backup-YYYYMMDDTHHMMSS.tar.gz
The backup includes:
- PocketBase SQLite database (
data.db,auxiliary.db) - All uploaded wedding photos and media files
- PocketBase logs and system state
Automatic Restoration
When deploying to a fresh server, the role automatically detects and restores from the latest backup:
# Normal deployment will auto-restore if backup exists
ansible-playbook playbooks/deploy-sigvild.yml
# Or deploy full infrastructure (includes auto-restore)
ansible-playbook site.yml
Manual Restoration
To restore data manually or from a specific backup:
# Restore with specific backup file
ansible-playbook playbooks/deploy-sigvild.yml --tags="restore" \
--extra-vars="sigvild_gallery_backup_local_path=/path/to/backup/directory"
# Force restoration (overwrite existing data)
ansible-playbook playbooks/deploy-sigvild.yml --tags="backend,restore"
Backup Management
# List available backups
ls -la ./backups/sigvild-gallery/
# Verify backup contents
tar -tzf ./backups/sigvild-gallery/sigvild-gallery-backup-YYYYMMDDTHHMMSS.tar.gz
# Extract backup for inspection (local)
tar -xzf ./backups/sigvild-gallery/sigvild-gallery-backup-YYYYMMDDTHHMMSS.tar.gz
Security Features
Environment Variables
- No .env files: Secrets managed via systemd Environment directives
- Vault encrypted: Passwords stored in Ansible vault
- Memory-only: Environment variables only exist in process memory
SystemD Sandboxing
NoNewPrivileges=yes: Prevents privilege escalationPrivateTmp=yes: Isolated temporary directoryProtectSystem=strict: Read-only filesystem protectionProtectHome=yes: Home directory protectionReadWritePaths: Only data directory is writable
Caddy Security
- Security headers: XSS protection, frame options, content type sniffing prevention
- CORS configuration: Restricted to frontend domain
- Rate limiting: API endpoint protection
- HTTPS only: Automatic TLS with Let's Encrypt
Directory Structure
/opt/sigvild-gallery/ # Application home
├── sigvild-gallery-server # Go binary
└── data/ # PocketBase data directory
├── data.db # SQLite database
└── storage/ # File uploads
/var/www/sigvild-gallery/ # Frontend web root
├── index.html # SvelteKit build
├── _app/ # Application assets
└── assets/ # Static assets
/etc/systemd/system/
└── sigvild-gallery.service # SystemD service
/etc/caddy/sites-enabled/
├── sigvild-frontend.caddy # Frontend configuration
└── sigvild-api.caddy # API proxy configuration
Build Process
The role performs local builds then transfers assets:
- Backend:
GOOS=linux GOARCH=amd64 go build -o sigvild-gallery-server . - Frontend:
npm run buildinsigvild-kit/directory - Transfer: Copy binary and sync frontend build to server
- Deploy: Update systemd service and Caddy configuration
Service Management
# Check service status
systemctl status sigvild-gallery
# View logs
journalctl -u sigvild-gallery -f
# Restart service
systemctl restart sigvild-gallery
# Reload Caddy configuration
systemctl reload caddy
Troubleshooting
Build Failures
- Ensure Go toolchain is available locally
- Verify
sigvild-kit/directory exists withpackage.json - Check Node.js and npm are installed for frontend builds
Service Startup Issues
- Check systemd logs:
journalctl -u sigvild-gallery - Verify binary permissions and ownership
- Ensure data directory is writable by service user
Domain Resolution
- Verify DNS records point to server IP
- Check Caddy logs:
journalctl -u caddy - Test local connectivity:
curl -H "Host: api.sigvild.no" http://localhost:8090
Dependencies
- caddy: Required for web server and reverse proxy
- systemd: Service management
- Local build tools: Go compiler, Node.js/npm
Files Created
/etc/systemd/system/sigvild-gallery.service/etc/caddy/sites-enabled/sigvild-frontend.caddy/etc/caddy/sites-enabled/sigvild-api.caddy/opt/sigvild-gallery/(application directory)/var/www/sigvild-gallery/(frontend files)
Data Protection
Backup Strategy
- Automated: Backup creation via dedicated playbook
- Comprehensive: Includes database, uploaded files, and system state
- Consistent: Service temporarily stopped during backup for data integrity
- Local storage: Backups stored in
./backups/sigvild-gallery/directory - Timestamped: Each backup includes ISO timestamp for easy identification
Recovery Process
- Automatic detection: Deployment automatically detects available backups
- Zero-downtime restore: Restoration happens before service startup
- Integrity verification: Backups verified before and after restoration
- Permission preservation: User/group ownership maintained during restore
Tags
sigvild: Complete Sigvild Gallery deploymentbackend: API service deploymentfrontend: Static site deploymentbuild: Local build processesservice: SystemD service managementcaddy: Caddy configurationverify: Post-deployment verificationbackup: Data backup operationsrestore: Data restoration operations