4ce4204b6c
CI / Lint (push) Failing after 2s
CI / Build (push) Has been skipped
SDK CI / PHP SDK (push) Failing after 1s
Split PHP SDK / PHP SDK tests (push) Failing after 1s
CI / Test (push) Failing after 1s
CI / Dashboard (push) Failing after 0s
SDK CI / JavaScript SDK (push) Failing after 0s
SDK CI / Python SDK (push) Failing after 2s
SDK CI / Java SDK (push) Failing after 1s
Split PHP SDK / Mirror sdk/php -> rmyndharis/openwa-php (push) Has been skipped
CI / Test (PostgreSQL migrations) (push) Failing after 7m47s
CI / Docker Build (push) Has been skipped
98 lines
2.9 KiB
Bash
Executable File
98 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# OpenWA backup.
|
|
#
|
|
# Captures EVERYTHING needed to restore a working install:
|
|
# - main.sqlite — auth (API keys) + audit log, ALWAYS SQLite (see app.module.ts)
|
|
# - data store — openwa.sqlite (SQLite) OR a pg_dump (when DATABASE_TYPE=postgres)
|
|
# - sessions/ — WhatsApp LocalAuth session data
|
|
# - media/ — locally-stored media (skipped automatically when using S3)
|
|
#
|
|
# The previous runbook backed up the wrong file (openwa.db) and omitted main.sqlite,
|
|
# so a "successful" backup silently lost every API key and all audit history.
|
|
#
|
|
# Usage:
|
|
# ./scripts/backup.sh
|
|
# Environment:
|
|
# OPENWA_DATA_DIR data directory (default: ./data)
|
|
# BACKUP_DIR where archives are written (default: ./backups)
|
|
# DATABASE_TYPE sqlite (default) | postgres
|
|
# For postgres: DATABASE_URL, or DATABASE_HOST/PORT/USERNAME/PASSWORD/NAME
|
|
#
|
|
set -euo pipefail
|
|
|
|
DATA_DIR="${OPENWA_DATA_DIR:-./data}"
|
|
BACKUP_DIR="${BACKUP_DIR:-./backups}"
|
|
DATABASE_TYPE="${DATABASE_TYPE:-sqlite}"
|
|
TIMESTAMP="$(date +%Y%m%d-%H%M%S)"
|
|
|
|
MAIN_DB="$DATA_DIR/main.sqlite"
|
|
DATA_DB="$DATA_DIR/openwa.sqlite"
|
|
SESSIONS_DIR="$DATA_DIR/sessions"
|
|
MEDIA_DIR="$DATA_DIR/media"
|
|
|
|
log() { echo "[backup] $*"; }
|
|
|
|
STAGE="$(mktemp -d)"
|
|
trap 'rm -rf "$STAGE"' EXIT
|
|
|
|
# Online SQLite backup (consistent without stopping the app) when sqlite3 is present,
|
|
# else a plain copy with a warning.
|
|
backup_sqlite() {
|
|
src="$1"
|
|
dest="$2"
|
|
if [ ! -f "$src" ]; then
|
|
log "WARN: $src not found — skipping"
|
|
return 0
|
|
fi
|
|
if command -v sqlite3 >/dev/null 2>&1; then
|
|
sqlite3 "$src" ".backup '$dest'"
|
|
else
|
|
log "WARN: sqlite3 not found — plain-copying $src (stop the app first for a consistent copy)"
|
|
cp "$src" "$dest"
|
|
fi
|
|
}
|
|
|
|
log "Backing up auth/audit DB (main.sqlite) — the API-key + audit store"
|
|
backup_sqlite "$MAIN_DB" "$STAGE/main.sqlite"
|
|
|
|
if [ "$DATABASE_TYPE" = "postgres" ]; then
|
|
log "Backing up data store via pg_dump"
|
|
if ! command -v pg_dump >/dev/null 2>&1; then
|
|
log "ERROR: DATABASE_TYPE=postgres but pg_dump is not installed"
|
|
exit 1
|
|
fi
|
|
if [ -n "${DATABASE_URL:-}" ]; then
|
|
pg_dump "$DATABASE_URL" >"$STAGE/database.sql"
|
|
else
|
|
PGPASSWORD="${DATABASE_PASSWORD:-}" pg_dump \
|
|
-h "${DATABASE_HOST:-localhost}" \
|
|
-p "${DATABASE_PORT:-5432}" \
|
|
-U "${DATABASE_USERNAME:-openwa}" \
|
|
"${DATABASE_NAME:-openwa}" >"$STAGE/database.sql"
|
|
fi
|
|
else
|
|
log "Backing up data store (openwa.sqlite)"
|
|
backup_sqlite "$DATA_DB" "$STAGE/openwa.sqlite"
|
|
fi
|
|
|
|
if [ -d "$SESSIONS_DIR" ]; then
|
|
log "Backing up WhatsApp sessions"
|
|
cp -r "$SESSIONS_DIR" "$STAGE/sessions"
|
|
else
|
|
log "WARN: $SESSIONS_DIR not found — skipping sessions"
|
|
fi
|
|
|
|
if [ -d "$MEDIA_DIR" ]; then
|
|
log "Backing up local media"
|
|
cp -r "$MEDIA_DIR" "$STAGE/media"
|
|
fi
|
|
|
|
mkdir -p "$BACKUP_DIR"
|
|
ARCHIVE="$BACKUP_DIR/openwa-backup-$TIMESTAMP.tar.gz"
|
|
tar -czf "$ARCHIVE" -C "$STAGE" .
|
|
|
|
log "Backup complete: $ARCHIVE"
|
|
log "Contents:"
|
|
tar -tzf "$ARCHIVE" | sed 's/^/[backup] /'
|