Backups
Schedule
Automated backups run daily at 4:00 AM UTC via cron.
# View the cron job
crontab -l
# 0 4 * * * /opt/camlab/backup.sh >> /opt/camlab/backups/backup.log 2>&1
Backup Scope
graph LR
cron["Cron<br>4 AM UTC"] --> script["backup.sh"]
script --> db["MySQL<br>Databases x3"]
script --> ghost["Ghost<br>Content x3"]
script --> n8n["n8n<br>Data"]
script --> runners["Runner<br>Configs x3"]
script --> env[".env +<br>compose"]
db & ghost & n8n & runners & env --> tar["camlab-backup-<br>DATE.tar.gz"]
What's Backed Up
| Component | Source | Method |
|---|---|---|
| MySQL databases (x3) | mysql container | mysqldump all 3 Ghost databases |
| Ghost content (x3) | ./ghost/<slug>/ |
tar archive of images, themes, data |
| n8n data | ./n8n/data/ |
tar archive of n8n database + credentials |
| Runner configs (x3) | ./runners/<slug>/claude-config/ |
tar archive of agent definitions + MCP configs |
| Environment file | .env |
Direct copy |
| Docker Compose | docker-compose.yml |
Direct copy |
Backup Location
/opt/camlab/backups/
├── backup.log # Cron output log
├── camlab-backup-YYYY-MM-DD.tar.gz # Daily archives
└── ...
Retention
Backups older than 7 days are automatically pruned by the backup script.
Restore Procedures
Full Restore
cd /opt/camlab
# Stop all services
docker compose down
# Extract backup
tar xzf backups/camlab-backup-YYYY-MM-DD.tar.gz -C /tmp/restore/
# Restore .env
cp /tmp/restore/.env /opt/camlab/.env
# Restore MySQL data
docker compose up -d mysql
# Wait for MySQL to be ready
docker exec -i mysql mysql -u root -p"<root-password>" < /tmp/restore/mysql-all-databases.sql
# Restore Ghost content
cp -r /tmp/restore/ghost/* /opt/camlab/ghost/
# Restore n8n data
cp -r /tmp/restore/n8n-data/* /opt/camlab/n8n/data/
# Restore runner configs
cp -r /tmp/restore/runners/* /opt/camlab/runners/
# Start everything
docker compose up -d
Single Database Restore
# Restore just one Ghost database
docker exec -i mysql mysql -u root -p"<root-password>" ghost_cam4 < /tmp/restore/ghost_cam4.sql
# Restart the Ghost instance
docker compose restart ghost-cam4
Single Blog Content Restore
# Restore images/themes for one blog
cp -r /tmp/restore/ghost/cam4/* /opt/camlab/ghost/cam4/
# Restart Ghost to pick up theme changes
docker compose restart ghost-cam4
Manual Backup
# Run the backup script manually
/opt/camlab/backup.sh
# Or just dump MySQL
docker exec mysql mysqldump -u root -p"<root-password>" --all-databases > /tmp/all-databases.sql