Docker Compose for PostgreSQL and pgAdmin on localhost
Run PostgreSQL and the pgAdmin web page on your computer with one docker compose command.
This file starts a PostgreSQL database and pgAdmin, the web tool for managing it. Set your values below, run docker compose up, open pgAdmin in the browser and add the server using the host name db.
Create your config file
Type your own values. The file below updates as you type, and nothing you type leaves your browser.
services:
db:
image: postgres:17
container_name: postgres-db
restart: unless-stopped
environment:
POSTGRES_DB: appdb
POSTGRES_USER: app
POSTGRES_PASSWORD: Change-me-123
ports:
- "5432:5432"
volumes:
- pg-data:/var/lib/postgresql/data
pgadmin:
image: dpage/pgadmin4
container_name: pgadmin
restart: unless-stopped
environment:
PGADMIN_DEFAULT_EMAIL: admin@example.com
PGADMIN_DEFAULT_PASSWORD: Change-admin-456
ports:
- "5050:80"
depends_on:
- db
volumes:
pg-data:How this setup works
Step-by-step setup
- Save the file above as docker-compose.yml.
- Start both: docker compose up -d.
- Open http://localhost:5050 and log in with admin@example.com and your pgAdmin password.
- Choose Add New Server. Under Connection set Host to db, Port to 5432, and enter the database user and password.
- Your apps on this computer connect to 127.0.0.1 port 5432.
What the important lines mean
- POSTGRES_DB, POSTGRES_USER and POSTGRES_PASSWORD create your database on the first start only.
- PGADMIN_DEFAULT_EMAIL and PGADMIN_DEFAULT_PASSWORD make the first pgAdmin login.
- The host name db works inside the Compose network because it is the service name.
- pg-data is a volume, so the data survives restarts.
Common errors and how to fix them
- pgAdmin cannot connect to server "localhost"
- Inside pgAdmin, localhost is the pgAdmin container itself. Use the host db and the internal port 5432.
- password authentication failed for user
- The password is only set on the first start. If you changed it later, run docker compose down -v to create a fresh volume, or change it with ALTER USER.
- pgAdmin: email is not valid
- pgAdmin refuses some example domains. Use a normal-looking address such as admin@example.com or your own.
- port is already allocated
- Another program uses that port, often an installed PostgreSQL on 5432. Change the left number of the port line.
Frequently asked questions
- Why do I use db and not localhost in pgAdmin?
- pgAdmin runs in its own container. From there, localhost means itself. The service name db points to the database container.
- How do I reset everything?
- Run docker compose down -v. It removes the containers and the data volumes, so the next start is clean.
- Is pgAdmin needed?
- No. It is only a web tool. You can remove that service and use psql or any other client.
Free tools that help
- Password generatorCreate a random password with the length and characters you choose. It runs in your browser, uses secure randomness and shows how strong it is.
- Common ports listSearch a list of common TCP and UDP port numbers: SSH 22, HTTP 80, HTTPS 443, MySQL 3306, PostgreSQL 5432 and more, with dev server ports.
Fix a problem with this setup
- Docker port already allocatedFix "port is already allocated" in Docker and Docker Compose: find the container or program that holds the port and free it.
- Docker container cannot reach localhostFix "connection refused" when an app in Docker calls localhost: use host.docker.internal, a Compose service name or host networking.
More container configs
- docker-compose for MongoDBRun a local MongoDB database with a password that keeps its data.
- docker-compose for PostgreSQLRun a local PostgreSQL database that keeps its data.
- docker-compose for MySQLRun a local MySQL database in Docker with your own user, password and port, and keep the data between restarts.
- docker-compose for RedisRun Redis in Docker with a password, saved data and a memory limit.
- docker-compose for WordPressRun WordPress and its database locally in Docker with one command and keep your site between restarts.
- Dockerfile for Node.jsA small, working Dockerfile for a Node.js app, with build step, non-root user and health check options.