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:
In pgAdmin, register the server with these values:
- host:
db - port:
5432 - username:
appuser - password:
secret123 - database:
appdborpostgres
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.
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.
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.
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. - '
localhostinside 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.

