From 8f93bb89f68d8ceb7e73dbaabd9e756f5cda7dea Mon Sep 17 00:00:00 2001 From: root Date: Sat, 23 May 2026 01:39:21 -0400 Subject: [PATCH] update Traefik --- scripts/backup-restore-guide.md | 111 ++++++++++++++++++++++++++++++++ traefik.yaml | 25 +++---- 2 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 scripts/backup-restore-guide.md diff --git a/scripts/backup-restore-guide.md b/scripts/backup-restore-guide.md new file mode 100644 index 0000000..62c3404 --- /dev/null +++ b/scripts/backup-restore-guide.md @@ -0,0 +1,111 @@ +# 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 + +```bash +cd ~/car_management_system + +# Default — saves to ./backups// +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. + +```bash +cd ~/car_management_system + +bash scripts/docker-prod-restore.sh backups/rentaldrivego-prod- --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, marketplace, 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: + +```bash +(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: +```bash +crontab -l +``` + +### Cleaning up old backups + +To keep only the last 7 days of backups, add a cleanup job: + +```bash +(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 + bash scripts/docker-prod-restore.sh /path/to/backup --yes + ``` + +--- + +## Verifying a Backup + +Check the backup directory contents and sizes: + +```bash +ls -lh backups/rentaldrivego-prod-/ +cat backups/rentaldrivego-prod-/manifest.txt +``` + +Test that the database dump is valid: + +```bash +pg_restore --list backups/rentaldrivego-prod-/postgres.dump | head -20 +``` diff --git a/traefik.yaml b/traefik.yaml index 0c32277..83a115e 100644 --- a/traefik.yaml +++ b/traefik.yaml @@ -1,32 +1,33 @@ services: traefik: image: traefik:latest - restart: unless-stopped command: - --api.dashboard=false - --api.insecure=false - --providers.docker=true - --providers.docker.exposedbydefault=false + - --providers.docker.network=traefik-proxy + - --providers.file.directory=/etc/traefik/dynamic + - --providers.file.watch=true - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 + - --entrypoints.web.http.redirections.entrypoint.to=websecure + - --entrypoints.web.http.redirections.entrypoint.scheme=https - --certificatesresolvers.letsencrypt.acme.tlschallenge=true - --certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL} - --certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json - - --entrypoints.web.http.redirections.entrypoint.to=websecure - - --entrypoints.web.http.redirections.entrypoint.scheme=https - - --providers.docker.network=traefik-proxy + restart: unless-stopped ports: - - "80:80" - - "443:443" - networks: - - traefik-proxy + - 80:80 + - 443:443 volumes: - traefik-letsencrypt:/letsencrypt - /var/run/docker.sock:/var/run/docker.sock:ro - -volumes: - traefik-letsencrypt: - + - ./dynamic:/etc/traefik/dynamic:ro + networks: + - traefik-proxy networks: traefik-proxy: external: true +volumes: + traefik-letsencrypt: