#!/usr/bin/env bash # ============================================================================= # BistroUsky — deploy skript (aktualizace běžící instance) # Spusť ze složky s kódem: bash deploy/deploy.sh # ============================================================================= set -euo pipefail RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERR]${NC} $*"; exit 1; } APP_DIR="/opt/eshop_bistrousky" APP_USER="root" PM2_APP="bistrousky" [[ $EUID -ne 0 ]] && error "Spusť jako root (sudo bash deploy/deploy.sh)" # ── 0. Záloha databáze před deploym ────────────────────────────────────── BACKUP_DIR="${APP_DIR}/backups" mkdir -p "$BACKUP_DIR" BACKUP_FILE="${BACKUP_DIR}/db_$(date +%Y%m%d_%H%M%S).sql.gz" info "Záloha DB → ${BACKUP_FILE}..." sudo -u postgres pg_dump bistrousky | gzip > "$BACKUP_FILE" # Ponechat pouze posledních 10 záloh ls -t "${BACKUP_DIR}"/db_*.sql.gz 2>/dev/null | tail -n +11 | xargs -r rm # ── 1. Synchronizace kódu ──────────────────────────────────────────────── info "Kopírování kódu do ${APP_DIR}..." rsync -a --delete \ --exclude='.env' \ --exclude='node_modules/' \ --exclude='.git/' \ --exclude='logs/' \ --exclude='backups/' \ ./ "$APP_DIR/" chown -R "$APP_USER:$APP_USER" "$APP_DIR" # ── 2. Závislosti (všechny — dev i prod, potřebné pro build) ───────────── info "Instalace závislostí..." sudo -u "$APP_USER" bash -c "cd $APP_DIR && npm ci --quiet" # ── 3. Prisma ───────────────────────────────────────────────────────────── info "Generování Prisma klienta..." sudo -u "$APP_USER" bash -c "cd $APP_DIR && npx prisma generate" info "Aplikace DB migrací..." sudo -u "$APP_USER" bash -c "cd $APP_DIR && npx prisma migrate deploy" # ── 4. Build ────────────────────────────────────────────────────────────── info "Produkční build (Next.js)..." sudo -u "$APP_USER" bash -c "cd $APP_DIR && npm run build" # ── 4b. Odstranit dev závislosti po buildu ──────────────────────────────── info "Odstraňování dev závislostí..." sudo -u "$APP_USER" bash -c "cd $APP_DIR && npm prune --omit=dev --quiet" # ── 4c. Statické soubory a .env do standalone ───────────────────────────── info "Kopírování statiky a .env do standalone..." cp -r "${APP_DIR}/.next/static" "${APP_DIR}/.next/standalone/.next/static" cp -r "${APP_DIR}/public" "${APP_DIR}/.next/standalone/public" cp "${APP_DIR}/.env" "${APP_DIR}/.next/standalone/.env" # ── 5. Restart aplikace (zero-downtime přes PM2 reload) ─────────────────── info "Reloading PM2..." mkdir -p "${APP_DIR}/logs" chown "$APP_USER:$APP_USER" "${APP_DIR}/logs" if sudo -u "$APP_USER" pm2 describe "$PM2_APP" &>/dev/null; then sudo -u "$APP_USER" bash -c "cd $APP_DIR && pm2 reload ecosystem.config.js --env production" else sudo -u "$APP_USER" bash -c "cd $APP_DIR && pm2 start ecosystem.config.js --env production" sudo -u "$APP_USER" pm2 save fi # ── 6. Zdravotní kontrola ──────────────────────────────────────────────── info "Čekám na nastartování aplikace..." sleep 5 HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:3000 || echo "000") if [[ "$HTTP_CODE" == "200" || "$HTTP_CODE" == "307" || "$HTTP_CODE" == "301" ]]; then info "Aplikace běží (HTTP ${HTTP_CODE}) ✓" else error "Aplikace neodpovídá (HTTP ${HTTP_CODE}) — zkontroluj: pm2 logs ${PM2_APP}" fi echo "" echo -e "${GREEN}=== Deploy dokončen ===${NC}" echo -e " Stav: $(sudo -u $APP_USER pm2 jlist | python3 -c "import sys,json; apps=json.load(sys.stdin); [print(a['name'],a['pm2_env']['status']) for a in apps if a['name']=='${PM2_APP}']" 2>/dev/null || echo 'viz pm2 list')" echo -e " Logy: ${YELLOW}pm2 logs ${PM2_APP}${NC}" echo ""