food-market/deploy/backup.sh
nurdotnet 5bcbff66de ci/deploy: GitHub Actions + Docker images + DB backup + 24x7 plan
.github/workflows/ci.yml — on push/PR:
  - backend job: dotnet restore/build/test with a live postgres service
  - web job: pnpm install + vite build + tsc, uploads dist artifact
  - pos job: windows-latest, dotnet publish self-contained win-x64
    single-file exe as artifact

.github/workflows/docker.yml — on push to main (if src changed) or manual:
  - api image → ghcr.io/nurdotnet/food-market-api:{latest,sha}
  - web image → ghcr.io/nurdotnet/food-market-web:{latest,sha}
  - uses buildx + GHA cache

deploy/Dockerfile.api — multi-stage (.NET 8 sdk → aspnet runtime),
  healthcheck on /health, App_Data + logs volumes mounted.

deploy/Dockerfile.web — node20 build → nginx 1.27 runtime; ships the
  Vite dist + nginx.conf that proxies /api, /connect, /health to api
  service and serves the SPA with fallback to index.html.

deploy/nginx.conf — SPA + API reverse-proxy configuration.

deploy/docker-compose.yml — production-shape stack: postgres 16 +
  api (from ghcr image) + web (from ghcr image), named volumes, env-
  driven tags so stage/prod can pin specific SHAs.

deploy/backup.sh — pg_dump wrapper with 3 modes: local (brew
  postgres), --docker (compose container), --remote HOST:PORT. Writes
  gzipped dumps to ~/food-market-backups, 30-day retention.

docs/24x7.md — explains where Claude/CI/stage live, which pieces
  depend on the Mac, and the exact steps to hand off secrets via
  ~/.food-market-secrets/ so I can push them into GitHub Secrets.

Next, once user supplies Proxmox + FTP + Telegram creds: stage deploy
workflow, notification workflow, and (optional) claude-runner VM so
I no longer depend on the Mac being awake.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 11:26:01 +05:00

42 lines
1.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Dumps the food-market Postgres DB to a timestamped gzipped file.
# Usage:
# deploy/backup.sh — local dev DB (postgres@14 via Unix socket)
# deploy/backup.sh --remote HOST:PORT — over network
# deploy/backup.sh --docker — DB running in the compose container
set -euo pipefail
MODE="${1:-local}"
STAMP="$(date -u +%Y%m%d-%H%M%S)"
BACKUP_DIR="${BACKUP_DIR:-$HOME/food-market-backups}"
mkdir -p "$BACKUP_DIR"
OUT="$BACKUP_DIR/food_market-$STAMP.sql.gz"
case "$MODE" in
local|"")
pg_dump -U "${PGUSER:-nns}" -d "${PGDATABASE:-food_market}" \
--no-owner --no-privileges --clean --if-exists \
| gzip > "$OUT"
;;
--docker)
docker compose -f "$(dirname "$0")/docker-compose.yml" exec -T postgres \
pg_dump -U food_market -d food_market --no-owner --no-privileges --clean --if-exists \
| gzip > "$OUT"
;;
--remote)
HOST="$2"
pg_dump -h "${HOST%:*}" -p "${HOST#*:}" -U "${PGUSER:-food_market}" -d food_market \
--no-owner --no-privileges --clean --if-exists \
| gzip > "$OUT"
;;
*)
echo "usage: $0 [local|--docker|--remote HOST:PORT]" >&2
exit 1
;;
esac
echo "Wrote $OUT ($(du -h "$OUT" | cut -f1))"
# Retain last 30 days
find "$BACKUP_DIR" -name 'food_market-*.sql.gz' -mtime +30 -delete 2>/dev/null || true