The runner executes each job in its own container on docker's default bridge network, so "localhost" never resolves to the docker host - smoke-qa's direct Postgres connection and Playwright/API HTTP calls need the bridge gateway IP instead. Bind the db port to that same gateway IP (not 0.0.0.0) so it stays reachable only from sibling containers, not off-box.