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.