
5 Things to Know Before Running Postgres in Docker in 2026
Jonas ScholzDocker is one of the easiest ways to run Postgres locally. You can start a database in seconds, connect your app, test migrations, and throw the whole thing away when you are done.
But Postgres is still a database. If you run it like a disposable web container, you will eventually lose data.
Here are the five things to know before running Postgres in Docker in 2026.
1. A one-line Docker command is enough for local development
For a quick local database, run:
docker run -d \
--name postgres-container \
-e POSTGRES_USER=myuser \
-e POSTGRES_PASSWORD=mypassword \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
postgres:17
That command does a lot:
--name postgres-containergives the container a stable name.POSTGRES_USERcreates a database user.POSTGRES_PASSWORDsets the password for that user.POSTGRES_DBcreates the first database.-p 5432:5432exposes Postgres on your local machine.postgres:17uses the official Postgres Docker image with a pinned major version.
Check that it is running:
docker ps
Connect from inside the container:
docker exec -it postgres-container psql -U myuser -d mydb
Or connect from your machine if you have psql installed:
psql -h localhost -p 5432 -U myuser -d mydb
For local development, this is usually enough.
2. Without a volume, your data is disposable
The most common Docker/Postgres mistake is forgetting persistent storage.
This command starts Postgres with a Docker volume:
docker volume create pgdata
docker run -d \
--name postgres-container \
-e POSTGRES_USER=myuser \
-e POSTGRES_PASSWORD=mypassword \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:17
The important part is:
-v pgdata:/var/lib/postgresql/data
That stores the Postgres data directory in a Docker volume called pgdata. If you remove and recreate the container, the data can survive because it lives outside the container layer.
To inspect volumes:
docker volume ls
docker volume inspect pgdata
For development, Docker volumes are usually simpler than bind mounts. For production, the important part is not the volume type; it is whether the storage is durable, backed up, monitored, and recoverable.
3. Docker Compose is better once an app is involved
Once your app needs to talk to Postgres, use Docker Compose. It gives you repeatable config and an internal network between services.
Create compose.yml:
services:
postgres:
image: postgres:17
container_name: postgres-container
restart: unless-stopped
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypassword
POSTGRES_DB: mydb
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U myuser -d mydb"]
interval: 30s
timeout: 5s
retries: 5
volumes:
pgdata:
Start it:
docker compose up -d
Stop it:
docker compose down
If another container needs to connect to the database, put it in the same Compose file and use the service name as the host:
services:
app:
image: my-app
environment:
DATABASE_URL: postgresql://myuser:mypassword@postgres:5432/mydb
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:17
Inside the Compose network, the database host is postgres, not localhost.
4. Backups are separate from Docker volumes
A Docker volume protects you from accidentally deleting the container. It does not protect you from:
- deleting the wrong rows.
- corrupting data.
- losing the server.
- running a bad migration.
- discovering that the disk is full.
Create a logical backup with pg_dump:
docker exec -t postgres-container \
pg_dump -U myuser -d mydb -Fc \
> backup-$(date +%F).dump
Restore it into an existing database:
cat backup-2026-07-02.dump | docker exec -i postgres-container \
pg_restore -U myuser -d mydb --clean --if-exists
For anything important, schedule backups, store them somewhere outside the server, and test restores. A backup you have never restored is mostly a comforting file.
5. Docker Postgres is great for development, but production has more work
Running Postgres in Docker for local development is easy. Running production Postgres in Docker is an operations job.
Before using it for a real app, make sure you have answers for:
- where backups are stored.
- how restores are tested.
- who watches disk usage.
- how Postgres upgrades happen.
- how security updates are applied.
- how clients connect privately.
- what happens when the host dies.
Self-hosting can still be the right choice. It is cheap, flexible, and educational. Just be honest about the work.
Use managed Postgres when you want the database, not the database operations.
FAQ
Can I run multiple Postgres containers at once?
Yes. Use different container names, different host ports, and different volumes:
docker run -d \
--name postgres-two \
-e POSTGRES_USER=myuser \
-e POSTGRES_PASSWORD=mypassword \
-e POSTGRES_DB=mydb \
-p 5433:5432 \
-v pgdata2:/var/lib/postgresql/data \
postgres:17
Should I use postgres:latest?
No. Use a pinned major version like postgres:17, or a pinned minor version when you need reproducible builds. Major upgrades should be deliberate.
Can I use this in production?
Yes, but only if you are ready to own backups, restores, monitoring, storage, security, and upgrades. For many small teams, managed Postgres is the better trade.
What should I read next?
Read 5 Best Practices for Postgres in Docker for the production checklist, and 5 Cheap Ways to Host Postgres if you are comparing hosting options.