Operations

Backups

Cleanmails stores all data in PostgreSQL. The included backup script uses pg_dump to create compressed backups with automatic rotation.

Quick Backup

bash
cd /opt/cleanmails
bash scripts/backup.sh

This creates a gzipped SQL dump in /opt/cleanmails/backups/ and automatically removes backups older than 7 (keeping the last 7).

Automated Daily Backup (Cron)

bash
# Add to crontab (crontab -e)
0 3 * * * cd /opt/cleanmails && bash scripts/backup.sh

This runs at 3 AM daily and creates a timestamped backup file.

Manual Backup (pg_dump)

bash
cd /opt/cleanmails
docker compose -f docker-compose.prod.yml exec -T postgres \
  pg_dump -U cleanmails cleanmails | gzip > backups/manual_backup.sql.gz

Restoring from Backup

bash
cd /opt/cleanmails

# Stop the application (keep postgres running)
docker compose -f docker-compose.prod.yml stop api worker frontend

# Restore the database
gunzip -c backups/cleanmails_backup_20240101_030000.sql.gz | \
  docker compose -f docker-compose.prod.yml exec -T postgres \
  psql -U cleanmails cleanmails

# Restart all services
docker compose -f docker-compose.prod.yml up -d
Stop the app before restoring

Always stop the API and worker containers before restoring. This prevents data conflicts while the database is being restored.

What's Included in PostgreSQL

The database contains all application data:

  • Users, roles, and JWT sessions
  • Workspaces and settings
  • Campaigns, steps, and delivery logs
  • Lead lists and all leads
  • Mailboxes (including AES-256-GCM encrypted credentials)
  • Email threads and replies
  • Webhook subscriptions and delivery logs
  • Integration configs
  • API keys (bcrypt hashed)
  • Warmup status and progress
  • License information

What's NOT in the Database

  • Uploaded files — Logos and CSVs in the uploads_data Docker volume
  • Redis data — Task queue state (reconstructed automatically)
  • SSL certificates — Stored in Caddy's caddy_data volume (auto-provisioned)
  • Environment file/opt/cleanmails/.env (back this up separately!)

Full System Backup

For a complete backup including uploads and config:

bash
cd /opt/cleanmails

# Database
bash scripts/backup.sh

# Environment and config
cp .env backups/env_backup
cp Caddyfile backups/Caddyfile_backup

# Uploads volume (find actual mount path)
docker cp $(docker compose -f docker-compose.prod.yml ps -q api):/app/uploads ./backups/uploads_backup

Backup Retention

The backup script automatically keeps the last 7 backups and removes older ones. To change this, edit MAX_BACKUPS=7 in scripts/backup.sh.

Backup File Sizes

Typical backup sizes (compressed with gzip):

Data VolumeApproximate Size
Fresh install< 1 MB
10k leads, 5 campaigns5-10 MB
100k leads, 50 campaigns50-100 MB