Skip to content
Latchkey

How to Run a Postgres Service Container in GitHub Actions

Service containers spin up a database or cache alongside your job so integration tests hit a real backend.

Declare backing services under services:. GitHub starts each container, waits on its health check, and exposes it to your steps on localhost.

Postgres with a health check

The options: health check makes the job wait until Postgres is accepting connections before steps run.

.github/workflows/ci.yml
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - run: npm test
        env:
          DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres

Gotchas

  • On runs-on: ubuntu-latest (job runs on the host) reach the service via localhost:5432. If your job runs in a container:, use the service name (postgres:5432) instead.
  • Without a health check, steps may start before the DB is ready and fail intermittently.
  • Map the port explicitly under ports: so the host can reach it.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →