Files
carmanagement/scripts/backup-restore-guide.md
T
root 8fc88ffc14
Build & Push / Pipeline Tests (push) Failing after 59s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Failing after 51s
Test / API Unit Tests (push) Has been skipped
Test / Homepage Unit Tests (push) Has been skipped
Test / Carplace Unit Tests (push) Has been skipped
Test / Admin Unit Tests (push) Has been skipped
Test / Dashboard Unit Tests (push) Has been skipped
Test / API Integration Tests (push) Has been skipped
fix production issues
2026-08-12 16:48:41 -04:00

3.7 KiB

Backup & Restore Guide

What gets backed up

File Contents
postgres.dump Full PostgreSQL database (pg_dump custom format)
api-uploads.tar.gz User-uploaded files (vehicle images, documents, etc.)
traefik-letsencrypt.tar.gz Let's Encrypt SSL certificates
volumes/ Raw Docker volume archives (Redis, pgmanage, etc.)
manifest.txt Backup metadata (timestamp, project name)

Note: The .env.docker.production file is NOT included in backups. Store it separately in a secure location (password manager, encrypted storage). You will need it to restore on a new server.


Running a Backup

cd ~/car_management_system

# Default — saves to ./backups/<timestamp>/
bash scripts/docker-prod-backup.sh

# Custom backup directory
bash scripts/docker-prod-backup.sh /mnt/external/backups

The script will create a timestamped directory, e.g.:

backups/rentaldrivego-prod-20260522T103000Z/

PostgreSQL does not need to be stopped. The script brings it up automatically if needed.


Running a Restore

Warning: Restore is destructive. It will overwrite the current database and uploaded files.

cd ~/car_management_system

bash scripts/docker-prod-restore.sh backups/rentaldrivego-prod-<timestamp> --yes

The --yes flag is required. Without it, the script exits with instructions.

What the restore does (in order)

  1. Stops all app services (api, dashboard, carplace, admin, pgmanage, redis, traefik)
  2. Starts PostgreSQL
  3. Restores the database with pg_restore --clean --if-exists
  4. Restores uploaded files into the api_uploads volume
  5. Restores Traefik SSL certificates
  6. Restores remaining Docker volumes (Redis, pgmanage)
  7. Starts all services back up

Automated Daily Backups (cron)

To schedule a daily backup at 3:00 AM:

(crontab -l 2>/dev/null; echo '0 3 * * * cd /root/car_management_system && bash scripts/docker-prod-backup.sh /root/car_management_system/backups >> /var/log/rentaldrivego-backup.log 2>&1') | crontab -

Verify the cron job was added:

crontab -l

Cleaning up old backups

To keep only the last 7 days of backups, add a cleanup job:

(crontab -l 2>/dev/null; echo '30 3 * * * find /root/car_management_system/backups -maxdepth 1 -name "rentaldrivego-prod-*" -mtime +7 -exec rm -rf {} +') | crontab -

Restoring on a Fresh Server

  1. Install Docker and Docker Compose on the new server
  2. Clone the repository
  3. Recreate .env.docker.production (from your secure backup of that file)
  4. Copy the backup directory to the new server
  5. Run the restore script:
    bash scripts/docker-prod-restore.sh /path/to/backup --yes
    

Verifying a Backup

Check the backup directory contents and sizes:

ls -lh backups/rentaldrivego-prod-<timestamp>/
cat backups/rentaldrivego-prod-<timestamp>/manifest.txt

Run the Phase 2 smoke check (required artifacts + non-empty manifest):

bash scripts/backup-restore-smoke-check.sh backups/rentaldrivego-prod-<timestamp>

Test that the database dump is valid:

pg_restore --list backups/rentaldrivego-prod-<timestamp>/postgres.dump | head -20

RPO / RTO evidence checklist

Record after each restore drill:

Field Target Actual
Backup timestamp
Restore start / end
RPO achieved (data lag) ≤ declared RPO
RTO achieved (time to healthy /ready) ≤ declared RTO
Smoke check PASS
App /health + /ready 200
Spot-check bookings / invoices / uploads OK

Declared targets live with ops owners; do not claim production ready without a dated drill that meets them.