Skip to content
Latchkey

Django "OperationalError: could not connect to server: Connection refused" in CI

Django tried to open a database connection and the TCP connect was refused. In CI this almost always means the Postgres service is not up yet, or the host name and port in DATABASES do not match how the service container is exposed.

What this error means

Migrations or tests fail with "django.db.utils.OperationalError: could not connect to server: Connection refused. Is the server running on host 'localhost' (127.0.0.1) and accepting TCP/IP connections on port 5432?"

Django
django.db.utils.OperationalError: could not connect to server: Connection refused
	Is the server running on host "localhost" (127.0.0.1) and accepting
	TCP/IP connections on port 5432?

Common causes

Django ran before the Postgres service was ready

The service container is still starting when migrations run. Without a health check, the DB port is not yet accepting connections.

Host or port mismatch with the service

The job connects to localhost but the service is only reachable by its service name, or the mapped port differs from the one in DATABASES.

How to fix it

Add a health check to the Postgres service

Gate the job until pg_isready passes so Django never connects too early.

.github/workflows/ci.yml
services:
  postgres:
    image: postgres:16
    env:
      POSTGRES_PASSWORD: postgres
    ports: ["5432:5432"]
    options: >-
      --health-cmd "pg_isready -U postgres"
      --health-interval 5s --health-timeout 5s --health-retries 10

Point DATABASE_URL at the right host

On GitHub-hosted runners the mapped service is reachable on localhost; align the URL with the exposed port.

.github/workflows/ci.yml
env:
  DATABASE_URL: postgres://postgres:postgres@localhost:5432/app_test

How to prevent it

  • Always add a pg_isready health check to the Postgres service.
  • Match the DATABASES host and port to how the service is exposed.
  • Read DATABASE_URL from one place so host and port cannot drift.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →