Docker
Postgres
pgAdmin 4
Connection Error
Troubleshooting

Docker - Postgres and pgAdmin 4 Connection refused

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When pgAdmin and PostgreSQL run in Docker, a connection refused error usually means pgAdmin is trying to connect to the wrong host, the database container is not ready yet, or PostgreSQL is not listening on the expected interface. The fix is usually in the container networking and startup assumptions, not in pgAdmin itself.

Use The Container Service Name, Not localhost

Inside a Docker Compose network, localhost means the current container, not another service. If pgAdmin is running in one container and PostgreSQL in another, the PostgreSQL host should be the Compose service name such as db.

A minimal Compose setup looks like this:

yaml
1services:
2  db:
3    image: postgres:16
4    environment:
5      POSTGRES_DB: appdb
6      POSTGRES_USER: appuser
7      POSTGRES_PASSWORD: secret123
8    ports:
9      - "5432:5432"
10    volumes:
11      - db-data:/var/lib/postgresql/data
12
13  pgadmin:
14    image: dpage/pgadmin4:8
15    environment:
16      PGADMIN_DEFAULT_EMAIL: [email protected]
17      PGADMIN_DEFAULT_PASSWORD: admin123
18    ports:
19      - "5050:80"
20    depends_on:
21      - db
22
23volumes:
24  db-data:

In pgAdmin, register the server with these values:

  • host: db
  • port: 5432
  • username: appuser
  • password: secret123
  • database: appdb or postgres

Using localhost from the pgAdmin container causes connection refusal because no PostgreSQL server is listening inside that pgAdmin container.

Confirm PostgreSQL Is Actually Running

Even with the correct hostname, pgAdmin can fail if PostgreSQL is still starting. Check the containers first.

bash
docker compose ps
docker compose logs db

Look for a log line indicating PostgreSQL is ready to accept connections. If the container is restarting repeatedly, the real problem may be an invalid environment variable, a bad mounted volume, or an incompatible leftover data directory.

Test Connectivity From Inside The Network

A quick network test helps separate pgAdmin configuration problems from PostgreSQL startup problems.

bash
docker compose exec db pg_isready -U appuser -d appdb

If pg_isready reports success, PostgreSQL is reachable from inside its own container. You can also confirm DNS resolution from the pgAdmin side by opening a shell in that container if the image supports it.

Understand Port Mapping Versus Container Networking

The published port mapping 5432:5432 is for connections from your host machine into the container. pgAdmin does not need that mapping when it talks to PostgreSQL over the internal Compose network.

That distinction matters:

  • host machine to Postgres uses localhost:5432
  • pgAdmin container to Postgres uses db:5432

Mixing those contexts is one of the most common causes of refusal errors.

Persisted Data Can Cause Startup Issues

If the Postgres container was started once with a different user or database configuration, the volume may preserve old state. Changing POSTGRES_USER or POSTGRES_DB later does not rewrite an already initialized cluster.

If this is a disposable development environment, remove the volume and recreate the stack.

bash
docker compose down -v
docker compose up -d

Do this only when you are willing to lose the stored database data.

Common Pitfalls

The most common mistake is entering localhost as the host in pgAdmin. In a multi-container setup, use the database service name instead.

Another mistake is assuming depends_on means PostgreSQL is ready. It only controls start order, not readiness. The database may still be initializing when pgAdmin first tries to connect.

A third issue is reusing an old volume with new credentials and expecting PostgreSQL to pick them up automatically. Initialization variables apply only when the data directory is first created.

Summary

  • In Docker Compose, pgAdmin should connect to PostgreSQL by service name, usually db.
  • 'localhost inside the pgAdmin container is the wrong host for the database container.'
  • Check container logs and readiness before blaming pgAdmin.
  • Remember that published ports are for host-to-container traffic, not container-to-container traffic.
  • If credentials changed after initialization, the persisted volume may be the real source of the problem.

Course illustration
Course illustration

All Rights Reserved.