121 lines
3.9 KiB
Bash
Executable File
121 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Export CaseGambling database (+ uploads) FROM Docker (production).
|
|
# Run this on the prod server next to docker-compose.yml.
|
|
#
|
|
# Usage:
|
|
# ./scripts/docker-db-export.sh
|
|
# ./scripts/docker-db-export.sh ./backups/my-backup
|
|
#
|
|
# Output:
|
|
# backups/casegambling-YYYYMMDD-HHMMSS/
|
|
# prod.db (+ optional -wal/-shm)
|
|
# uploads/
|
|
# manifest.txt
|
|
# backups/casegambling-YYYYMMDD-HHMMSS.tar.gz
|
|
#
|
|
# Then copy the .tar.gz to your machine and import locally:
|
|
# ./scripts/local-db-import.sh ./backups/casegambling-….tar.gz
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
if [[ -f "$SCRIPT_DIR/../docker-compose.yml" ]]; then
|
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
elif [[ -f "$SCRIPT_DIR/docker-compose.yml" ]]; then
|
|
ROOT="$SCRIPT_DIR"
|
|
else
|
|
echo "Error: docker-compose.yml not found near $SCRIPT_DIR" >&2
|
|
exit 1
|
|
fi
|
|
cd "$ROOT"
|
|
|
|
ENV_FILE="${ENV_FILE:-.env.prod}"
|
|
COMPOSE=(docker compose)
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
COMPOSE=(docker compose --env-file "$ENV_FILE")
|
|
fi
|
|
|
|
SERVICE="${SERVICE:-casegambling}"
|
|
STAMP="$(date +%Y%m%d-%H%M%S)"
|
|
OUT="${1:-$ROOT/backups/casegambling-$STAMP}"
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "Error: docker not found" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! "${COMPOSE[@]}" ps -q "$SERVICE" >/dev/null 2>&1; then
|
|
echo "Error: compose service '$SERVICE' not found" >&2
|
|
echo "Tip: run from the folder that has docker-compose.yml" >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$OUT"
|
|
|
|
echo "==> Exporting Docker database → $OUT/prod.db"
|
|
echo " service: $SERVICE · volume path: /data/prod.db"
|
|
|
|
TMP_UPLOADS="$(mktemp -d)"
|
|
cleanup() {
|
|
rm -rf "$TMP_UPLOADS"
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
WAS_RUNNING=0
|
|
if [[ -n "$("${COMPOSE[@]}" ps -q --status running "$SERVICE" 2>/dev/null || true)" ]]; then
|
|
WAS_RUNNING=1
|
|
fi
|
|
|
|
# Prefer a consistent SQLite snapshot inside a running container
|
|
if [[ "$WAS_RUNNING" -eq 1 ]] \
|
|
&& "${COMPOSE[@]}" exec -T "$SERVICE" sh -c 'command -v sqlite3 >/dev/null && test -f /data/prod.db'; then
|
|
"${COMPOSE[@]}" exec -T "$SERVICE" sh -c "sqlite3 /data/prod.db \".backup '/tmp/prod-export.db'\""
|
|
"${COMPOSE[@]}" cp "$SERVICE:/tmp/prod-export.db" "$OUT/prod.db"
|
|
"${COMPOSE[@]}" exec -T "$SERVICE" rm -f /tmp/prod-export.db >/dev/null 2>&1 || true
|
|
else
|
|
# Safe file copy: stop if running so WAL is flushed
|
|
if [[ "$WAS_RUNNING" -eq 1 ]]; then
|
|
echo "==> Stopping $SERVICE for a consistent copy"
|
|
"${COMPOSE[@]}" stop "$SERVICE" >/dev/null
|
|
fi
|
|
"${COMPOSE[@]}" cp "$SERVICE:/data/prod.db" "$OUT/prod.db"
|
|
"${COMPOSE[@]}" cp "$SERVICE:/data/prod.db-wal" "$OUT/prod.db-wal" 2>/dev/null || true
|
|
"${COMPOSE[@]}" cp "$SERVICE:/data/prod.db-shm" "$OUT/prod.db-shm" 2>/dev/null || true
|
|
if [[ "$WAS_RUNNING" -eq 1 ]]; then
|
|
echo "==> Starting $SERVICE"
|
|
"${COMPOSE[@]}" start "$SERVICE" >/dev/null 2>&1 || "${COMPOSE[@]}" up -d "$SERVICE" >/dev/null
|
|
fi
|
|
fi
|
|
|
|
# Also write as dev.db so local import can use either name
|
|
cp -f "$OUT/prod.db" "$OUT/dev.db"
|
|
[[ -f "$OUT/prod.db-wal" ]] && cp -f "$OUT/prod.db-wal" "$OUT/dev.db-wal"
|
|
[[ -f "$OUT/prod.db-shm" ]] && cp -f "$OUT/prod.db-shm" "$OUT/dev.db-shm"
|
|
|
|
echo "==> Exporting Docker uploads → $OUT/uploads"
|
|
mkdir -p "$OUT/uploads"
|
|
if "${COMPOSE[@]}" cp "$SERVICE:/app/uploads/." "$TMP_UPLOADS/" 2>/dev/null; then
|
|
cp -a "$TMP_UPLOADS"/. "$OUT/uploads/" 2>/dev/null || true
|
|
else
|
|
echo " (no uploads or empty volume)"
|
|
fi
|
|
|
|
{
|
|
echo "exported_at=$STAMP"
|
|
echo "source=docker"
|
|
echo "service=$SERVICE"
|
|
echo "database=prod.db"
|
|
echo "uploads=uploads/"
|
|
} > "$OUT/manifest.txt"
|
|
|
|
TAR="$OUT.tar.gz"
|
|
tar -czf "$TAR" -C "$(dirname "$OUT")" "$(basename "$OUT")"
|
|
|
|
DB_SIZE="$(du -h "$OUT/prod.db" | awk '{print $1}')"
|
|
UPLOAD_COUNT="$(find "$OUT/uploads" -type f 2>/dev/null | wc -l | tr -d ' ')"
|
|
|
|
echo "==> Archive: $TAR"
|
|
echo " db size: $DB_SIZE · uploads files: $UPLOAD_COUNT"
|
|
echo "==> Done. On your laptop:"
|
|
echo " scp user@prod:$TAR ./backups/"
|
|
echo " ./scripts/local-db-import.sh ./backups/$(basename "$TAR")"
|