Backup & Restore
What to Back Up
Section titled “What to Back Up”| Component | Contains |
|---|---|
| PostgreSQL database | All application data — reports, schedules, users, permissions |
.env file | Passwords, SMTP config, domain configuration |
| License file | License activation key |
| Keycloak database | Users, roles, IdP federation config (shared PostgreSQL instance) |
All report templates, data sources, and configuration are stored in the database.
Database Backup
Section titled “Database Backup”Manual Backup
Section titled “Manual Backup”# Full database dump (custom format, recommended)docker exec presswerk-postgres pg_dump \ -U presswerk \ -d presswerk \ --format=custom \ --file=/tmp/backup.dump
# Copy to hostdocker cp presswerk-postgres:/tmp/backup.dump ./presswerk_backup_$(date +%Y%m%d).dumpAutomated Backup (Cron)
Section titled “Automated Backup (Cron)”Create /opt/presswerk/backup.sh:
#!/bin/bashset -euo pipefail
BACKUP_DIR="/var/backups/presswerk"RETENTION_DAYS=30TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
docker exec presswerk-postgres pg_dump \ -U presswerk -d presswerk \ --format=custom \ --file=/tmp/backup.dump
docker cp presswerk-postgres:/tmp/backup.dump "$BACKUP_DIR/presswerk_${TIMESTAMP}.dump"docker exec presswerk-postgres rm /tmp/backup.dump
find "$BACKUP_DIR" -name "presswerk_*.dump" -mtime +${RETENTION_DAYS} -deletechmod +x /opt/presswerk/backup.shecho "0 2 * * * root /opt/presswerk/backup.sh" > /etc/cron.d/presswerk-backupRestore
Section titled “Restore”Full Restore
Section titled “Full Restore”# Stop application (keep database running)docker compose stop app keycloak
# Drop and recreate the databasedocker exec presswerk-postgres dropdb -U presswerk presswerkdocker exec presswerk-postgres createdb -U presswerk presswerk
# Restoredocker cp presswerk_backup.dump presswerk-postgres:/tmp/restore.dumpdocker exec presswerk-postgres pg_restore \ -U presswerk -d presswerk \ --no-owner --no-privileges \ /tmp/restore.dump
# Restartdocker compose up -dDatabase migrations run automatically on startup — restoring an older backup is safe.
Keycloak Backup
Section titled “Keycloak Backup”Keycloak shares the PostgreSQL instance. A full pg_dump includes Keycloak data in the keycloak schema.
To back up Keycloak separately:
docker exec presswerk-postgres pg_dump \ -U presswerk -d presswerk \ --schema=keycloak \ --format=custom \ --file=/tmp/keycloak_backup.dumpRealm Export (alternative)
Section titled “Realm Export (alternative)”docker exec presswerk-keycloak \ /opt/keycloak/bin/kc.sh export \ --realm presswerk \ --dir /tmp/export
docker cp presswerk-keycloak:/tmp/export/presswerk-realm.json ./keycloak_realm.jsonRealm exports include client config and roles but not user credentials. Use database backup for full recovery.
Offsite Storage
Section titled “Offsite Storage”# S3-compatible storageaws s3 cp presswerk_backup.dump s3://your-bucket/presswerk/backups/
# rsync to remote serverrsync -az /var/backups/presswerk/ backup-server:/backups/presswerk/Verification
Section titled “Verification”Always test backups by restoring to a temporary database:
docker exec presswerk-postgres createdb -U presswerk presswerk_testdocker cp backup.dump presswerk-postgres:/tmp/verify.dumpdocker exec presswerk-postgres pg_restore \ -U presswerk -d presswerk_test \ --no-owner --no-privileges /tmp/verify.dumpdocker exec presswerk-postgres dropdb -U presswerk presswerk_test