diff --git a/.agent/workflows/deploy.md b/.agent/workflows/deploy.md index 7f105b9..641095a 100644 --- a/.agent/workflows/deploy.md +++ b/.agent/workflows/deploy.md @@ -9,7 +9,7 @@ description: Deployment munkafolyamata — lokális teszttől a stagingen át a - **Nincs Dokploy / registry push** — a deploy natív Docker Compose-zal, a szerveren buildelve történik. - **Környezetenként külön compose fájl**: `docker-compose.staging.yml` (app: 127.0.0.1:8081, saját Mongo) és `docker-compose.prod.yml` (app: 8080). A két környezet ugyanazon a hoston, külön hálózaton és volume-mal fut. - **Környezeti változók**: kötelező `.env.staging` / `.env.production` fájlból jönnek (minta: `.env.staging.example`, `.env.production.example`). Bizalmas értékeknek (MONGO_ROOT_PASSWORD, MONGODB_URI) **nincs fallback** — hiányzó env hangosan hibázik. -- **Staging megkülönböztetés**: a `NEXT_PUBLIC_DEPLOY_ENV=staging` build arg amber banner-t jelenít meg a weboldalon; a Content Editor is staging feliratot kap. +- **Staging megkülönböztetés**: a `NEXT_PUBLIC_DEPLOY_ENV=staging` build arg amber banner-t jelenít meg a weboldalon. ## Előfeltételek @@ -44,6 +44,7 @@ Bármely lépés hibája azonnal leállítja a folyamatot. Paraméterek környez 1. Kötelező `.env.` fájl betöltése (`--env-file` a compose-nak). 2. `docker compose -f docker-compose..yml up --build --force-recreate -d` — a friss Dockerfile/build-arg változások is érvényesüljenek. 3. Healthcheck: max 60s-ig kérdezi a `http://localhost:/api/health`-t (staging: 8081, prod: 8080). Sikertelenség esetén app-logok kiírása + exit 1. +4. **Payload admin-seedelés** (MITHOME-97): healthcheck után meghívja a Payload beépített `POST /api/users/first-register` endpointját az `.env.`-ben megadott `ADMIN_EMAIL`/`ADMIN_PASSWORD`-del. Ez az endpoint csakis akkor enged létrehozni felhasználót, ha a `users` collection teljesen üres — ezért idempotens: egy vadonatúj adatbázisnál (első deploy, vagy volume-törlés utáni újrakezdés) automatikusan létrehozza az ismert admin fiókot, minden további deployon pedig 403-at kap és ártalmatlanul kihagyja (a jelszót utólag sosem írja felül). Ha az `ADMIN_EMAIL`/`ADMIN_PASSWORD` hiányzik az env fájlból, ezt a lépést egyszerűen kihagyja (figyelmeztetéssel, nem hibával) — ilyenkor az első felhasználót manuálisan kell létrehozni `/admin` alatt. ## Tartalom publikálása (Payload admin) diff --git a/.env.production.example b/.env.production.example index c00f5cd..99dcb2a 100644 --- a/.env.production.example +++ b/.env.production.example @@ -12,6 +12,16 @@ MONGO_ROOT_PASSWORD=changeme # environmenttel. PAYLOAD_SECRET=changeme +# Payload admin — ismert, biztosan létező admin fiók (MITHOME-97). A +# deploy.sh minden deploy után meghívja a Payload "first-register" REST +# endpointját ezekkel az adatokkal: teljesen friss (üres users collection-ű) +# adatbázisnál létrehozza ezt a fiókot, egyébként (ha már van user) +# ártalmatlanul kihagyja — nem írja felül a jelszót utólag. Generálj egyedi, +# erős jelszót (pl. jelszókezelővel), NE ossz meg értéket a staginggel; a +# hiányzó két érték esetén a deploy.sh csak kihagyja ezt a lépést. +ADMIN_EMAIL=admin@mozdit.hu +ADMIN_PASSWORD=changeme + # Publikus site URL (beég build időben a Dockerfile-ba) NEXT_PUBLIC_SITE_URL=https://mozdit.hu diff --git a/.env.staging.example b/.env.staging.example index 9598a65..6a5f280 100644 --- a/.env.staging.example +++ b/.env.staging.example @@ -12,6 +12,16 @@ MONGO_ROOT_PASSWORD=changeme # environmenttel. PAYLOAD_SECRET=changeme +# Payload admin — ismert, biztosan létező admin fiók (MITHOME-97). A +# deploy.sh minden deploy után meghívja a Payload "first-register" REST +# endpointját ezekkel az adatokkal: teljesen friss (üres users collection-ű) +# adatbázisnál létrehozza ezt a fiókot, egyébként (ha már van user) +# ártalmatlanul kihagyja — nem írja felül a jelszót utólag. Generálj egyedi, +# erős jelszót (pl. jelszókezelővel); a hiányzó két érték esetén a +# deploy.sh csak kihagyja ezt a lépést, nem hibázik el. +ADMIN_EMAIL=admin@mozdit.hu +ADMIN_PASSWORD=changeme + # Publikus site URL (beég build időben a Dockerfile-ba) NEXT_PUBLIC_SITE_URL=https://stage.mozdit.hu diff --git a/deploy.sh b/deploy.sh index 87ce062..9c1bfa1 100755 --- a/deploy.sh +++ b/deploy.sh @@ -42,8 +42,12 @@ 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 az APP_PORT-ot, ezért a healthcheckhez expliciten kiolvassuk. -APP_PORT_VALUE="$(grep -E '^APP_PORT=' "$ENV_FILE" | tail -n 1 | cut -d= -f2- | tr -d '[:space:]' | tr -d '"' | tr -d "'")" +# 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..." @@ -53,15 +57,61 @@ docker compose --env-file "$ENV_FILE" -f "$COMPOSE_FILE" up --build --force-recr # 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" - echo "✅ Deploy sikeres: [$ENV]" - exit 0 + HEALTHY=1 + break fi sleep 2 done -echo "❌ Healthcheck sikertelen: $HEALTH_URL" -docker compose -f "$COMPOSE_FILE" logs app --tail 50 -exit 1 +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 @- <