#!/usr/bin/env bash # Import SQLite DB (+ uploads) into the CaseGambling Docker container # Usage: # ./scripts/db-import.sh ./backups/casegambling-20260116-203000 # ./db-import.sh ./casegambling-20260116-203000.tar.gz set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" # Project root: folder that contains docker-compose.yml if [[ -f "$SCRIPT_DIR/docker-compose.yml" ]]; then ROOT="$SCRIPT_DIR" elif [[ -f "$SCRIPT_DIR/../docker-compose.yml" ]]; then ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" else ROOT="$SCRIPT_DIR" fi # Resolve backup path from the caller's working directory (before any cd) if [[ -z "${1:-}" ]]; then echo "Usage: $0 " >&2 echo "Example: $0 ./backups/casegambling-20260116-203000.tar.gz" >&2 exit 1 fi if [[ "$1" = /* ]]; then SRC="$1" else SRC="$(pwd)/$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}" TMP="" cleanup() { if [[ -n "$TMP" && -d "$TMP" ]]; then rm -rf "$TMP" fi } trap cleanup EXIT is_archive() { case "$1" in *.tar.gz|*.tgz) return 0 ;; *) return 1 ;; esac } if [[ -f "$SRC" ]] && is_archive "$SRC"; then echo "==> Extracting $(basename "$SRC")" TMP="$(mktemp -d)" tar -xzf "$SRC" -C "$TMP" # Prefer a single top-level directory from the archive mapfile -t DIRS < <(find "$TMP" -mindepth 1 -maxdepth 1 -type d | sort) if [[ ${#DIRS[@]} -ge 1 ]]; then SRC="${DIRS[0]}" else SRC="$TMP" fi elif [[ -f "$SRC" ]]; then echo "Error: not a directory or .tar.gz archive: $SRC" >&2 exit 1 fi if [[ ! -d "$SRC" ]]; then echo "Error: backup not found: $SRC" >&2 echo "Pass a folder or a .tar.gz produced by ./scripts/db-export.sh" >&2 exit 1 fi DB="$SRC/prod.db" if [[ ! -f "$DB" ]]; then if [[ -f "$SRC/dev.db" ]]; then DB="$SRC/dev.db" else echo "Error: no prod.db (or dev.db) in $SRC" >&2 ls -la "$SRC" >&2 || true exit 1 fi fi echo "==> Stopping $SERVICE (safe SQLite replace)" "${COMPOSE[@]}" stop "$SERVICE" 2>/dev/null || docker stop "$SERVICE" 2>/dev/null || true echo "==> Clearing old SQLite sidecars on volume" "${COMPOSE[@]}" run --rm --no-deps --entrypoint sh "$SERVICE" -c \ 'rm -f /data/prod.db-wal /data/prod.db-shm' >/dev/null echo "==> Importing database ← $DB" "${COMPOSE[@]}" cp "$DB" "$SERVICE:/data/prod.db" if [[ -f "$SRC/prod.db-wal" ]]; then "${COMPOSE[@]}" cp "$SRC/prod.db-wal" "$SERVICE:/data/prod.db-wal" fi if [[ -f "$SRC/prod.db-shm" ]]; then "${COMPOSE[@]}" cp "$SRC/prod.db-shm" "$SERVICE:/data/prod.db-shm" fi if [[ -d "$SRC/uploads" ]]; then echo "==> Importing uploads" "${COMPOSE[@]}" run --rm --no-deps --entrypoint sh "$SERVICE" -c \ 'rm -rf /app/uploads/* /app/uploads/.[!.]* 2>/dev/null; mkdir -p /app/uploads' >/dev/null "${COMPOSE[@]}" cp "$SRC/uploads/." "$SERVICE:/app/uploads/" fi echo "==> Starting $SERVICE" "${COMPOSE[@]}" start "$SERVICE" 2>/dev/null || "${COMPOSE[@]}" up -d "$SERVICE" echo "==> Done. Check: ${COMPOSE[*]} logs -f --tail=50"