From 2d55791458350e568861cffb255916ee9d172c52 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 6 Jun 2026 20:46:52 +0000 Subject: [PATCH] fix(deploy): PostgREST env + remove dead nextjs service from compose MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build was failing on the 'Start Docker stack' step with two issues: 1. PGRST_DB_URI not set — the env var was only in the 'Deploy' step, which runs after PostgREST has already started. PostgREST booted with a blank DB URI and the step exited 1. 2. docker-compose.yml had a 'nextjs' service with env_file: ../.env.production, but .env.production is written later by the 'Deploy' step. docker compose validates the entire compose file on 'up' and bailed because the path didn't exist yet. The 'nextjs' service is dead code anyway: PM2 runs Next.js directly from $APP_DIR, never through docker. Removed it. Also fixed: 'docker compose up -d db postgrest minio minio_init' referenced services that don't exist in the compose file (Postgres runs on the host, not in docker). Changed to just 'postgrest', and the pg_isready check now uses host psql directly instead of 'docker compose exec -T db'. Changes: - deploy/docker-compose.yml: drop nextjs service, keep only postgrest - .gitea/workflows/deploy.yml: - Add PGRST_DB_URI / PGRST_DB_ANON_ROLE / PGRST_SERVER_PORT to the 'Start Docker stack' step env - Write them to $APP_DIR/.env so docker compose picks them up - 'docker compose up -d postgrest' (was: db postgrest minio minio_init) - pg_isready check uses host psql (was: docker compose exec -T db) --- .gitea/workflows/deploy.yml | 22 ++++++++++++++---- deploy/docker-compose.yml | 46 ++++++------------------------------- 2 files changed, 25 insertions(+), 43 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 8ca1290..d9550b3 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -25,6 +25,13 @@ jobs: MINIO_ROOT_USER: ${{ secrets.MINIO_ROOT_USER }} MINIO_ROOT_PASSWORD: ${{ secrets.MINIO_ROOT_PASSWORD }} POSTGREST_JWT_SECRET: ${{ secrets.POSTGREST_JWT_SECRET }} + + # PostgREST — needs the DB URI at start time (it reads env + # from the container, not from .env.production which is + # written later by the Deploy step). + PGRST_DB_URI: ${{ secrets.PGRST_DB_URI }} + PGRST_DB_ANON_ROLE: ${{ secrets.PGRST_DB_ANON_ROLE }} + PGRST_SERVER_PORT: ${{ secrets.PGRST_SERVER_PORT }} run: | APP_DIR=/home/tyler/route-commerce mkdir -p $APP_DIR @@ -92,15 +99,22 @@ jobs: echo "MINIO_ROOT_USER=${MINIO_ROOT_USER}" echo "MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}" echo "POSTGREST_JWT_SECRET=${POSTGREST_JWT_SECRET}" + echo "PGRST_DB_URI=${PGRST_DB_URI}" + echo "PGRST_DB_ANON_ROLE=${PGRST_DB_ANON_ROLE:-anon}" + echo "PGRST_SERVER_PORT=${PGRST_SERVER_PORT:-3000}" echo "POSTGREST_HOST_PORT=$POSTGREST_HOST_PORT" echo "NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL" } >> .env # Bring the stack up fresh — --force-recreate ensures no stale - # network/container references from prior failed attempts - docker compose up -d --force-recreate db postgrest minio minio_init - # Wait for Postgres healthcheck + # network/container references from prior failed attempts. + # Only `postgrest` lives in docker; Postgres itself runs on the + # host (see the migrations step below, which uses + # `psql -h 127.0.0.1`). + docker compose up -d --force-recreate postgrest + # Wait for Postgres to accept connections on the host. + # The DB is on 127.0.0.1, not in a docker service. for i in $(seq 1 30); do - if docker compose exec -T db pg_isready -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" > /dev/null 2>&1; then + if PGPASSWORD="${POSTGRES_PASSWORD}" psql -h 127.0.0.1 -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -c "SELECT 1" > /dev/null 2>&1; then echo "Postgres is ready" break fi diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index 0dc22f1..27930f6 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -2,17 +2,14 @@ # docker-compose.yml — production stack consumed by deploy.sh # ============================================================================= # -# The host-side ports (POSTGREST_HOST_PORT, NEXTJS_HOST_PORT) are written by -# deploy.sh into .env.production. We interpolate from there with ${VAR:-3011} -# so a manual `docker compose up` without the deploy script still works. +# Only `postgrest` lives in docker. Postgres itself runs on the host +# (the deploy workflow applies migrations via `psql -h 127.0.0.1`). +# Next.js runs under PM2 on the host — it is NOT a docker service. # -# Note on networking: the Next.js container calls PostgREST on -# `host.docker.internal:POSTGREST_HOST_PORT` so the inlined -# NEXT_PUBLIC_API_URL (a localhost URL, per the deploy contract) resolves -# correctly. On Linux you may need to add -# extra_hosts: -# - "host.docker.internal:host-gateway" -# which is included below for that reason. +# The host-side port (POSTGREST_HOST_PORT) is written by the deploy +# workflow into $APP_DIR/.env. We interpolate from there with +# ${VAR:-3011} so a manual `docker compose up` without the deploy +# script still works. # ============================================================================= name: prod-app # default project name; deploy.sh overrides with -p @@ -39,32 +36,3 @@ services: timeout: 3s retries: 6 - nextjs: - # Build context is the workspace root (one level up from this file). - build: - context: .. - dockerfile: deploy/Dockerfile.nextjs - container_name: prod-app-nextjs - restart: unless-stopped - ports: - - "${NEXTJS_HOST_PORT:-3012}:3000" - environment: - # Runtime vars — these can change without rebuilding. NEXT_PUBLIC_* - # is also exported here for completeness, but the BROWSER's view of - # NEXT_PUBLIC_API_URL is baked in at build time (see Dockerfile). - NODE_ENV: production - PORT: 3000 - NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL} - env_file: - - ../.env.production # server-side secrets read at runtime - extra_hosts: - # Lets the container reach the host on the dynamically allocated port. - - "host.docker.internal:host-gateway" - depends_on: - postgrest: - condition: service_healthy - healthcheck: - test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/api/health"] - interval: 10s - timeout: 3s - retries: 6