#!/usr/bin/env bash # Cerbero_mcp — deploy script per VPS produzione. # # Pre-requisiti sul VPS (NON gestiti da questo script): # 1. Docker Engine ≥ 24 + plugin docker compose installati. # 2. DNS A record `cerbero-mcp.tielogic.xyz` → IP del VPS. # 3. Porte 80 e 443 aperte sul firewall (per ACME + traffico HTTPS). # 4. PAT Gitea con scope `read:package`, salvato in env `$GITEA_PAT`. # 5. Username Gitea in env `$GITEA_USER` (default: adriano). # 6. Secret JSON exchange + token bearer disponibili in $SECRETS_SRC # (default: ~/cerbero-secrets/), che lo script copierà in # $DEPLOY_DIR/secrets/ con permessi 600. # # Idempotente: rieseguibile per aggiornamenti. set -euo pipefail DEPLOY_DIR="${DEPLOY_DIR:-/opt/cerbero-mcp}" SECRETS_SRC="${SECRETS_SRC:-$HOME/cerbero-secrets}" GITEA_USER="${GITEA_USER:-adriano}" GITEA_REPO_URL="${GITEA_REPO_URL:-ssh://git@git.tielogic.xyz:222/Adriano/Cerbero-mcp.git}" REGISTRY="${REGISTRY:-git.tielogic.xyz}" DOMAIN="${DOMAIN:-cerbero-mcp.tielogic.xyz}" AUDIT_LOG_DIR="${AUDIT_LOG_DIR:-/var/log/cerbero-mcp}" echo "=== Cerbero_mcp deploy → $DEPLOY_DIR (domain $DOMAIN) ===" # ────────────────────────────────────────────────────────────── # 1. Verifica pre-requisiti # ────────────────────────────────────────────────────────────── command -v docker >/dev/null || { echo "FATAL: docker non installato"; exit 1; } docker compose version >/dev/null || { echo "FATAL: docker compose plugin assente"; exit 1; } if [ -z "${GITEA_PAT:-}" ]; then echo "FATAL: env GITEA_PAT non settata. Export del PAT con scope read:package prima." exit 1 fi if [ ! -d "$SECRETS_SRC" ]; then echo "FATAL: secrets src dir $SECRETS_SRC non esiste." echo " Atteso contenere: deribit.json bybit.json hyperliquid.json alpaca.json" echo " macro.json sentiment.json core.token observer.token" exit 1 fi # Check DNS resolution (warning only, non blocca) ip_resolved=$(getent hosts "$DOMAIN" | awk '{print $1}' | head -1 || true) if [ -z "$ip_resolved" ]; then echo "WARN: $DOMAIN non risolve via DNS — TLS Let's Encrypt fallirà finché DNS non propaga." else echo "DNS $DOMAIN → $ip_resolved" fi # ────────────────────────────────────────────────────────────── # 2. Login al container registry # ────────────────────────────────────────────────────────────── echo "=== docker login $REGISTRY ===" echo "$GITEA_PAT" | docker login "$REGISTRY" -u "$GITEA_USER" --password-stdin # ────────────────────────────────────────────────────────────── # 3. Setup dir + clone/pull repo # ────────────────────────────────────────────────────────────── sudo mkdir -p "$DEPLOY_DIR" sudo chown "$USER:$USER" "$DEPLOY_DIR" if [ -d "$DEPLOY_DIR/.git" ]; then echo "=== Aggiornamento repo $DEPLOY_DIR ===" git -C "$DEPLOY_DIR" pull --ff-only else echo "=== Clone repo $GITEA_REPO_URL → $DEPLOY_DIR ===" git clone "$GITEA_REPO_URL" "$DEPLOY_DIR" fi cd "$DEPLOY_DIR" # ────────────────────────────────────────────────────────────── # 4. Copia secrets con permessi 600 # ────────────────────────────────────────────────────────────── mkdir -p secrets echo "=== Copia secrets da $SECRETS_SRC ===" for f in deribit.json bybit.json hyperliquid.json alpaca.json macro.json sentiment.json core.token observer.token; do if [ -f "$SECRETS_SRC/$f" ]; then cp "$SECRETS_SRC/$f" "secrets/$f" chmod 600 "secrets/$f" echo " ok: secrets/$f" else echo " WARN: $SECRETS_SRC/$f assente — il servizio relativo fallirà al boot." fi done # ────────────────────────────────────────────────────────────── # 5. Crea/aggiorna .env (preserva esistente) # ────────────────────────────────────────────────────────────── if [ ! -f .env ]; then echo "=== Creazione .env iniziale (testnet di default) ===" cat > .env <" echo " Audit: tail -f $AUDIT_LOG_DIR/*.audit.jsonl" echo " Restart: docker compose -f docker-compose.prod.yml --env-file .env restart " echo " Stop: docker compose -f docker-compose.prod.yml --env-file .env down"