76 lines
2.8 KiB
Bash
Executable File
76 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# backup.sh — Create a full backup of all Cloud Elves services
|
|
#
|
|
# Usage: ./scripts/backup.sh [destination_dir]
|
|
#
|
|
# Creates a timestamped tarball containing volume-level backups of all services.
|
|
# Run from the ce-infra repo root directory.
|
|
# Requires SSH access to box.cloud-elves.eu as root.
|
|
|
|
set -euo pipefail
|
|
|
|
HOST="root@box.cloud-elves.eu"
|
|
SSH_KEY="${SSH_KEY:-$HOME/.ssh/id_ed25519_ce}"
|
|
SSH="ssh -i $SSH_KEY $HOST"
|
|
SCP="scp -i $SSH_KEY"
|
|
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
DEST_DIR="${1:-./backups}"
|
|
BACKUP_NAME="ce-backup-${TIMESTAMP}"
|
|
REMOTE_TMP="/tmp/${BACKUP_NAME}"
|
|
|
|
echo "=== Cloud Elves Backup — ${TIMESTAMP} ==="
|
|
echo ""
|
|
|
|
# Create local destination
|
|
mkdir -p "${DEST_DIR}"
|
|
|
|
# Create remote temp directory
|
|
echo "[1/7] Preparing..."
|
|
$SSH "mkdir -p ${REMOTE_TMP}"
|
|
|
|
# Stop services for consistent backup (databases stay up for pg_dump)
|
|
echo "[2/7] Stopping application services for consistent backup..."
|
|
$SSH "cd /opt/services && docker compose stop gitea outline dex lldap gitea-runner caddy"
|
|
|
|
# Gitea: pg_dump + data volume
|
|
echo "[3/7] Backing up Gitea (database + data)..."
|
|
$SSH "cd /opt/services && docker compose exec -T gitea-db pg_dump -U gitea gitea | gzip > ${REMOTE_TMP}/gitea-db.sql.gz"
|
|
$SSH "docker run --rm -v services_gitea-data:/data -v ${REMOTE_TMP}:/backup alpine tar czf /backup/gitea-data.tar.gz -C /data ."
|
|
|
|
# Outline: pg_dump + data volume
|
|
echo "[4/7] Backing up Outline (database + uploads)..."
|
|
$SSH "cd /opt/services && docker compose exec -T outline-db pg_dump -U outline outline | gzip > ${REMOTE_TMP}/outline-db.sql.gz"
|
|
$SSH "docker run --rm -v services_outline-data:/data -v ${REMOTE_TMP}:/backup alpine tar czf /backup/outline-data.tar.gz -C /data ."
|
|
|
|
# LLDAP: SQLite volume
|
|
echo "[5/7] Backing up LLDAP (user directory)..."
|
|
$SSH "docker run --rm -v services_lldap-data:/data -v ${REMOTE_TMP}:/backup alpine tar czf /backup/lldap-data.tar.gz -C /data ."
|
|
|
|
# Dex: SQLite volume
|
|
echo "[6/7] Backing up Dex (auth database)..."
|
|
$SSH "docker run --rm -v services_dex-data:/dex -v ${REMOTE_TMP}:/backup alpine tar czf /backup/dex-data.tar.gz -C /dex ."
|
|
|
|
# Restart services
|
|
echo "[7/7] Restarting services..."
|
|
$SSH "cd /opt/services && docker compose up -d"
|
|
|
|
# Bundle everything and download
|
|
echo ""
|
|
echo "Downloading backup..."
|
|
$SSH "cd /tmp && tar cf ${BACKUP_NAME}.tar -C ${REMOTE_TMP} ."
|
|
$SCP "${HOST}:/tmp/${BACKUP_NAME}.tar" "${DEST_DIR}/${BACKUP_NAME}.tar"
|
|
|
|
# Clean up remote
|
|
$SSH "rm -rf ${REMOTE_TMP} /tmp/${BACKUP_NAME}.tar"
|
|
|
|
# Show result
|
|
BACKUP_SIZE=$(du -h "${DEST_DIR}/${BACKUP_NAME}.tar" | cut -f1)
|
|
echo ""
|
|
echo "=== Backup complete ==="
|
|
echo "File: ${DEST_DIR}/${BACKUP_NAME}.tar (${BACKUP_SIZE})"
|
|
echo ""
|
|
echo "Contents:"
|
|
tar tf "${DEST_DIR}/${BACKUP_NAME}.tar" | sed 's/^/ /'
|
|
echo ""
|
|
echo "Downtime was ~30 seconds while services were stopped for consistency."
|