Backup & Maintenance
PicFast includes a Maintenance Dashboard in the admin console to view disk health, database statistics, and pHash coverage, along with a built-in cleanup tool. For deeper operations, the picfast maintenance CLI handles consistency checks, backups, restores, and thumbnail repairs.
Admin Dashboard
Navigate to Maintenance in the admin console to monitor system health and perform routine cleanups:
- Disk Health: Real-time storage capacity, usage, and inode statistics for the local backend.
- Database Stats: Overview of row counts, sizes, and pHash calculation coverage.
- Cleanup Tool: Identify and delete unlinked objects from the storage backend (files without a database record).
- Risk Audit: Check for configurations that might pose a security or operational risk.
CLI: Before you run
- Use the same configuration as the running instance (
config.yaml/ environment) so the CLI can reach PostgreSQL and your storage backends. - In Docker Compose examples below, replace
<service>with your actual Compose service name for PicFast (many examples useapp; yours may differ — checkdocker-compose.yml). - Large deployments: prefer a maintenance window —
doctorand full backups can read many objects.
Command shape
docker compose exec <service> picfast maintenance <subcommand> [flags] Use picfast maintenance --help and picfast maintenance <subcommand> --help for flags (--json, --all, --pg-dump-container, etc.).
Subcommands
| Subcommand | Role |
|---|---|
doctor | Read‑only check of DB rows, stored objects, and thumbnails. |
backup | Writes a PostgreSQL custom‑format dump and can package object payloads into an archive. |
inspect | Validates manifest.json and checksums inside a backup tarball. |
restore | Preflight by default; --apply performs writes. Restoring into a non‑empty database requires --force. |
repair-thumbnails | Rebuilds missing thumbnails from source objects (dry‑run unless --apply). |
recalc-phash | Recalculates missing perceptual hashes (pHash) for all eligible images. |
Typical order
- Check:
picfast maintenance doctor --all --batch-size 500 - Backup:
picfast maintenance backup --output /app/data/backups/picfast-backup.tar.gz(adjust path to match your volume mounts) - Verify archive:
picfast maintenance inspect /app/data/backups/picfast-backup.tar.gz - Restore (on the target host, after checks):
picfast maintenance restore … --apply— add--forceonly when you intend to overwrite a non‑empty database.
PostgreSQL client tools
If the host does not have pg_dump / pg_restore, the CLI can shell into a Postgres container (e.g. --pg-dump-container / --pg-restore-container) — see --help on backup and restore.
Automated Backups
Use host cron to schedule recurring backups — no code changes needed.
Two complementary strategies:
| Type | Frequency | Scope | Retention |
|---|---|---|---|
| db-only | Hourly | PostgreSQL metadata only | Last 48 copies |
| full | Daily | Database + object files | Last 7 copies |
Step 1: Database backup script
Create /opt/picfast/backup-db.sh:
#!/bin/bash
set -euo pipefail
CONTAINER="${1:-picfast-db}"
BACKUP_DIR="${2:-/opt/picfast/data/backups}"
DB_USER="${3:-picfast}"
DB_NAME="${4:-picfast}"
RETENTION="${5:-48}"
TIMESTAMP=$(date +%Y%m%d-%H%M)
OUTPUT="$BACKUP_DIR/db-$TIMESTAMP.dump.gz"
mkdir -p "$BACKUP_DIR"
docker exec "$CONTAINER" pg_dump --format=custom -U "$DB_USER" -d "$DB_NAME" \
| gzip > "$OUTPUT"
echo "Backup written: $OUTPUT ($(du -h "$OUTPUT" | cut -f1))"
# Purge expired backups
ls -1t "$BACKUP_DIR"/db-*.dump.gz 2>/dev/null \
| tail -n +$((RETENTION + 1)) \
| xargs -r rm -v chmod +x /opt/picfast/backup-db.sh Step 2: Full backup script
Create /opt/picfast/backup-full.sh:
#!/bin/bash
set -euo pipefail
PROJECT_DIR="${1:-/opt/picfast}"
COMPOSE_FILE="${2:-$PROJECT_DIR/docker/docker-compose.yml}"
RETENTION="${3:-7}"
TIMESTAMP=$(date +%Y%m%d)
OUTPUT="$PROJECT_DIR/data/backups/full-$TIMESTAMP.tar.gz"
cd "$PROJECT_DIR"
docker compose -f "$COMPOSE_FILE" run --rm app \
picfast maintenance backup \
--output "/app/data/backups/full-$TIMESTAMP.tar.gz"
echo "Full backup written: $OUTPUT"
ls -1t "$PROJECT_DIR"/data/backups/full-*.tar.gz \
| tail -n +$((RETENTION + 1)) \
| xargs -r rm -v chmod +x /opt/picfast/backup-full.sh Step 3: Cron schedule
crontab -e # PicFast automated backups
0 * * * * /opt/picfast/backup-db.sh picfast-db /opt/picfast/data/backups picfast picfast 48
0 3 * * * /opt/picfast/backup-full.sh /opt/picfast /opt/picfast/docker/docker-compose.yml 7 Step 4 (optional): Offsite sync
Push backup directory and static files to remote storage with rclone:
30 3 * * * rclone sync /opt/picfast/data/backups remote:bucket/picfast-backups
30 3 * * * rclone sync /opt/picfast/data/uploads remote:bucket/picfast-uploads
30 3 * * * rclone sync /opt/picfast/data/thumbnails remote:bucket/picfast-thumbnails Restore from backup
# Database only
gunzip -c /opt/picfast/data/backups/db-20260728-1400.dump.gz | \
docker exec -i picfast-db pg_restore --clean --if-exists --no-owner -U picfast -d picfast
# Full recovery
docker compose -f docker/docker-compose.yml run --rm app \
picfast maintenance restore /app/data/backups/full-20260728.tar.gz --apply --force Full archive specification
Manifest schema, objects.jsonl vs checksum ledger, compatibility rules, and safety notes for operators and contributors live in the PicFast repo:
docs/maintenance.md.