#!/bin/bash # mozdIT Deploy Script — natív docker compose, Dokploy nélkül # Használat: ./deploy.sh [staging|production] # A szerveren fut (git pull + rebuild + indítás). # Compose fájl és port env-enként különbözik. set -euo pipefail ENV="$1" if [ "$ENV" != "staging" ] && [ "$ENV" != "production" ]; then echo "Hiba: Hiányzó vagy érvénytelen környezet paraméter." echo "Használat: ./deploy.sh staging VAGY ./deploy.sh production" exit 1 fi # WHY: staging és production külön compose fájlt és portot használ, hogy # ugyanazon a szerveren ne ütközzenek (prod 8080, staging 8081). COMPOSE_FILE="docker-compose.${ENV}.yml" DEFAULT_PORT=8080 if [ "$ENV" = "staging" ]; then DEFAULT_PORT=8081 fi echo "🚀 Deploy indítása: [$ENV] környezet (${COMPOSE_FILE})" # 1. Kód frissítése echo "📦 Kód frissítése a main ágról..." git pull origin main # Deploy version = git short SHA; baked into the image and served via /api/health # so "which build is live?" is a single curl away. export DEPLOY_VERSION="$(git rev-parse --short HEAD)" # 2. Környezeti változók (.env.) ENV_FILE=".env.${ENV}" if [ ! -f "$ENV_FILE" ]; then echo "❌ Hiba: $ENV_FILE fájl nem található." echo " Másold le a .env.staging.example / .env.production.example fájlt $ENV_FILE néven, és töltsd ki." exit 1 fi echo "🔑 Környezeti változók betöltése ($ENV_FILE)..." # WHY: a --env-file kapcsoló csak a compose változó-helyettesítését táplálja; # a shell nem látja belőle ezeket az értékeket, ezért a healthcheckhez és az # admin-seedeléshez expliciten kiolvassuk. env_value() { grep -E "^$1=" "$ENV_FILE" | tail -n 1 | cut -d= -f2- | tr -d '[:space:]' | tr -d '"' | tr -d "'" } APP_PORT_VALUE="$(env_value APP_PORT)" # 3. Docker konténerek újraépítése és indítása echo "🐳 Build és indítás..." # A friss Dockerfile- vagy build-arg-változásoknak is új konténerben kell érvényesülniük. docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up --build --force-recreate -d # 4. Healthcheck echo "⏳ Healthcheck (max 60s)..." HEALTH_URL="http://localhost:${APP_PORT_VALUE:-$DEFAULT_PORT}/api/health" HEALTHY=0 for i in $(seq 1 30); do if curl -sf "$HEALTH_URL" > /dev/null 2>&1; then echo "✅ Healthcheck OK: $HEALTH_URL" HEALTHY=1 break fi sleep 2 done if [ "$HEALTHY" -ne 1 ]; then echo "❌ Healthcheck sikertelen: $HEALTH_URL" docker compose -f "$COMPOSE_FILE" logs app --tail 50 exit 1 fi # 5. Payload admin felhasználó biztosítása (MITHOME-97 follow-up) # # WHY: minden friss adatbázisú deploy (első staging/prod indítás, vagy egy # volume-törlés utáni újrakezdés) a Payload "Create first user" képernyőjét # mutatná — valaki ott manuálisan hozná létre a saját fiókját, ami könnyen # elmarad vagy elfelejtődik, és ismeretlen/inkonzisztens admin-hozzáférést # eredményez környezetenként. Payload REST API-ja egy beépített # `POST //first-register` endpointot ad erre — DE csakis # akkor enged bármit létrehozni, ha a `users` collection még teljesen üres # (0 dokumentum); ha már van akár egy felhasználó is, 403 Forbidden-t ad. # Ez pont idempotenssé teszi: minden deploy után lefuttatjuk, első alkalommal # létrehozza az ismert admin fiókot ADMIN_EMAIL/ADMIN_PASSWORD alapján, # utána minden további deploy-on ártalmatlanul 403-at kap és kihagyja. ADMIN_EMAIL_VALUE="$(env_value ADMIN_EMAIL)" ADMIN_PASSWORD_VALUE="$(env_value ADMIN_PASSWORD)" if [ -z "$ADMIN_EMAIL_VALUE" ] || [ -z "$ADMIN_PASSWORD_VALUE" ]; then echo "⚠️ ADMIN_EMAIL/ADMIN_PASSWORD nincs beállítva $ENV_FILE-ban — admin-seedelés kihagyva." echo " (Egy teljesen friss adatbázisnál manuálisan kell létrehozni az első usert /admin alatt.)" else echo "👤 Admin felhasználó biztosítása..." ADMIN_HTTP_CODE="$(curl -sS -o /tmp/mozdit-admin-seed-response.json -w '%{http_code}' \ -X POST "http://localhost:${APP_PORT_VALUE:-$DEFAULT_PORT}/api/users/first-register" \ -H 'Content-Type: application/json' \ --data-binary @- <