diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 96b9c55..effdd0e 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -12,7 +12,8 @@ name: Deploy to TrueNAS # # Compose project name is pinned to "cannamanage" so it updates the existing # containers and reuses the persistent "cannamanage_pgdata" volume on the host. -# Live ports: backend 8081->8080, frontend 3000, db 5432 +# Live host ports: frontend 3000, backend 8081->8080 (LAN, healthcheck/debug). +# db is internal-only (no host publish) — reachable as db:5432 on the compose net. on: push: @@ -101,15 +102,24 @@ jobs: - name: Verify frontend run: | - for i in $(seq 1 10); do - if wget -q -O /dev/null http://192.168.188.119:3000; then - echo "✅ Frontend responding on :3000" + set -euo pipefail + # Probe the frontend on its own loopback INSIDE the container via the + # bundled node runtime. This is network-namespace-independent (no + # reliance on the host port being wired during a mid-recreate window, + # which caused a transient false-failure previously) and needs no + # wget/curl in the image. Any HTTP status < 500 counts as "up" — the + # root path returns 307 -> /login when unauthenticated, which is healthy. + echo "Waiting for frontend on container loopback :3000 ..." + for i in $(seq 1 20); do + if docker exec cannamanage-frontend node -e "require('http').get('http://127.0.0.1:3000/',r=>process.exit(r.statusCode<500?0:1)).on('error',()=>process.exit(1))"; then + echo "✅ Frontend responding after ${i} attempt(s)" exit 0 fi - echo " attempt $i/10 — waiting 5s" + echo " attempt $i/20 — waiting 5s" sleep 5 done - echo "❌ Frontend did not respond" + echo "❌ Frontend did not respond — recent logs:" + $COMPOSE logs --tail=40 frontend exit 1 - name: Prune dangling images diff --git a/docker-compose.truenas.yml b/docker-compose.truenas.yml index 89f3e24..9c037b9 100644 --- a/docker-compose.truenas.yml +++ b/docker-compose.truenas.yml @@ -14,6 +14,12 @@ # -p cannamanage up -d --build --remove-orphans services: db: + # Internal-only: drop the host :5432 publish inherited from docker-compose.yml. + # Postgres must not be exposed to the LAN. The backend reaches it over the + # compose network (db:5432) and the deploy's ALTER USER reconcile uses + # `docker exec`, so no published host port is needed. (!override [] replaces + # the inherited ports list — compose otherwise concatenates lists.) + ports: !override [] # POSTGRES_PASSWORD only takes effect on FIRST volume init; the existing # cannamanage_pgdata volume keeps its current role password. The live role # password is rotated out-of-band via `ALTER USER` to match ${DB_PASSWORD}.