The 'cp -f deploy/docker-compose.yml ...' was sitting AFTER
'docker compose down' in the step. 'docker compose down' reads
and validates the compose file on the server — so the old copy
(with the dead nextjs service and its env_file: ../.env.production
reference) was still being read, and docker compose bailed on the
missing .env.production file before the copy could overwrite it.
Moved the config-file seeding to the top of the step, right after
'mkdir -p $APP_DIR'. Now the new compose file is in place before
either 'docker compose down' or 'docker compose up' runs.
The 'Start Docker stack' step used '[ -f ... ] || cp' for
docker-compose.yml, which only copied the file on the first
deploy. Subsequent deploys kept the stale copy on the server.
The stale copy still had the dead 'nextjs' service with
'env_file: ../.env.production', which docker compose validates
on every 'up' and bailed because .env.production is written
later by the 'Deploy' step.
Changed to unconditional 'cp -f' so the server always has the
latest compose file.
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)
The Start Docker stack and Deploy steps referenced docker-compose.yml at
the repo root, but the file moved to deploy/ as part of the deploy.sh
refactor. The cp commands failed with 'cannot stat docker-compose.yml'
and the deploy step aborted.
Updated both cp paths to deploy/docker-compose.yml. The cd $APP_DIR and
docker compose -f $APP_DIR/docker-compose.yml references are unchanged
because they point at the deployed copy in APP_DIR, not the repo.
- Delete .gitea/workflows/build.yml (typecheck/lint only; caused confusion)
- Rewrite .gitea/workflows/deploy.yml as a thin wrapper that calls
./deploy/deploy.sh, matching the design in deploy/GITEA_SETUP.md
(Option B). The 14512-byte inline deploy is removed; deploy.sh is the
source of truth for the deploy mechanism.
- Fix runs-on to [self-hosted, ubuntu-latest] (matches the actual labels
registered on crispygoat-host-runner; the previous [.., linux, ..] was
unmatchable, which is why runs were stuck in the queue)
Ports the deploy pipeline from the Gitea main fork (commit 7ddb06d's deploy
toolkit) into the Auth.js v5 / NextAuth tree:
- .gitea/workflows/deploy.yml: inline deploy that brings up the Docker
stack, applies migrations, builds Next.js, and runs the app under PM2.
Swapped Better Auth env vars (BETTER_AUTH_SECRET/URL, NEXT_PUBLIC_BETTER_AUTH_URL)
for Auth.js v5 names (AUTH_SECRET/URL, NEXT_PUBLIC_AUTH_URL). Dropped
NEXT_PUBLIC_SUPABASE_URL/ANON_KEY (Supabase removal in progress). Added
GOOGLE_CLIENT_ID/SECRET + ALLOW_DEV_LOGIN for the Auth.js Google provider
and dev credentials path. Switched runs-on from 'ubuntu-latest' to the
self-hosted runner labels matching build.yml.
- deploy/: idempotent deploy toolkit (deploy.sh, docker-compose.yml,
Dockerfile.nextjs, nginx.conf.template, .env.production.example, healthcheck.sh,
Makefile, deploy/.gitignore). No auth/Supabase dependencies — pure infra.
- deploy/.env.production.example: renamed NEXTAUTH_SECRET/NEXTAUTH_URL
(v4) to AUTH_SECRET/AUTH_URL (v5) and added the v5-specific vars
(NEXT_PUBLIC_AUTH_URL, GOOGLE_*, ALLOW_DEV_LOGIN).
Build pipeline is now end-to-end:
build.yml → typecheck + lint + build (uses [self-hosted, linux, ubuntu-latest])
deploy.yml → start docker stack + migrations + build + PM2 restart
Storage / admin code ports (MinIO via @/lib/storage, Supabase removal,
admin-permissions rewrite) are tracked separately — they require porting
the storage and admin code first; the deploy pipeline itself is ready
to run against the Auth.js world.