#!/usr/bin/env bash set -euo pipefail # ============================================================================= # Outline Wiki Backup Script # Backs up PostgreSQL database and file storage from Docker containers. # # Usage: # ./outline-backup.sh [backup_dir] # # Crontab (daily at 3 AM): # 0 3 * * * /path/to/outline-backup.sh /backups/outline >> /var/log/outline-backup.log 2>&1 # ============================================================================= BACKUP_DIR="${1:-/backups/outline}" DATE=$(date +%Y-%m-%d_%H%M) RETENTION_DAYS=14 # DokPloy names containers ${COMPOSE_PROJECT}-${SERVICE}-1. APP_NAME is set # to the compose project name in the .env file, so derive the container # names from that. Allow overrides via env vars for portability. PROJECT="${APP_NAME:-outline}" POSTGRES_CONTAINER="${POSTGRES_CONTAINER:-${PROJECT}-postgres-1}" OUTLINE_CONTAINER="${OUTLINE_CONTAINER:-${PROJECT}-outline-1}" mkdir -p "$BACKUP_DIR" echo "=== Outline Backup — $DATE ===" # PostgreSQL dump echo "Backing up PostgreSQL from $POSTGRES_CONTAINER..." docker exec "$POSTGRES_CONTAINER" pg_dump -U outline -Fc outline \ > "$BACKUP_DIR/outline-db-$DATE.dump" echo " Database: outline-db-$DATE.dump" # File storage backup echo "Backing up file storage from $OUTLINE_CONTAINER..." docker cp "$OUTLINE_CONTAINER:/var/lib/outline/data" - \ | gzip > "$BACKUP_DIR/outline-files-$DATE.tar.gz" echo " Files: outline-files-$DATE.tar.gz" # Prune old backups echo "Pruning backups older than $RETENTION_DAYS days..." find "$BACKUP_DIR" -type f -mtime +$RETENTION_DAYS -delete echo "=== Backup complete ==="