The dev PostgREST (started outside docker compose for local development)
and the production PostgREST (started by docker compose up) were both
trying to bind 127.0.0.1:3001. Even with fuser -k in the deploy cleanup,
something on tyler's host (likely a process supervisor restarting the
dev PostgREST) keeps reclaiming 3001 between our check and the
docker bind.
Move the production PostgREST to host port 3011, keeping the container's
internal port at 3001 (PostgREST's default). This lets dev and prod
coexist on the same host without fighting over a port.
Update NEXT_PUBLIC_API_URL to http://localhost:3011 in:
- Build step env (so the build bakes in the right URL)
- Start Docker stack .env append (so docker compose + app see the URL)
- Deploy step .env.production writing (so runtime app uses 3011)
The previous attempt's `docker compose down` removed the project's
network, but on the subsequent `docker compose up`, the postgrest
container was being recreated rather than created from scratch, and
its network attachment still pointed to the now-orphaned old network
ID. The new db/minio containers attached to the freshly-created
network fine; only postgrest failed with 'network ... not found'.
`-d --force-recreate` tells docker compose to throw away any
existing container state and build from scratch, eliminating stale
network references.
On hosts with leftover dev processes or stuck containers from prior
attempts, docker compose fails with 'address already in use' when
trying to bind PostgREST to 127.0.0.1:3001. The previous deploy
attempt actually got as far as starting Postgres and MinIO, then
PostgREST failed at port binding — leaving the Postgres container
running, which would persist for the next attempt and keep
re-occupying 3001 indirectly.
Add a defensive pre-check: if 3001 is bound, kill the holder
(fuser -k) and remove any docker container publishing 3001, then
docker compose down --remove-orphans to clear stuck state. Sleep 3
to let the kernel release the port.
Same first-deploy bootstrap pattern as .env.example: 'Start Docker stack'
needs docker-compose.yml at $APP_DIR for 'docker compose up', and
'Apply migrations' needs supabase/migrations/ at $APP_DIR for psql.
Neither was copied there until the 'Deploy' step runs at the end of
the job — so the first deploy on a fresh host fails before any
runtime file is ever placed.
Each step now seeds the file/dir it needs from the workspace before
using it. The 'Deploy' step's later copy remains as a refresh for
subsequent deploys.
The Start Docker stack step does `cd $APP_DIR && [ -f .env ] || cp .env.example .env`
but never ensured .env.example existed in APP_DIR. The rsync in the Deploy step
also doesn't copy it. The first deploy on a fresh host therefore failed with
'cp: cannot stat .env.example' before ever bringing up the stack.
Fix: copy .env.example from the workspace into APP_DIR if it isn't already
there, before the cd.