Run a Web App and Database Together with Docker Compose
Procedures / docker-webapp-db.html
A procedure to start an application and PostgreSQL together and connect them, including the connection and readiness issues that most often block people.
"How do I run my web app and database together with Docker?"
This is the procedure for starting an application and PostgreSQL together with Docker Compose instead of installing each separately. It also covers the connection issue that most often blocks people.
Prerequisites
- Docker with Compose v2 installed (check with
docker compose version) - An application that listens on port 8000
Step 1 — Create the compose file
Create compose.yaml in the project root.
services:
db:
image: postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: appdb
volumes:
- dbdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
interval: 5s
timeout: 5s
retries: 10
web:
build: .
depends_on:
db:
condition: service_healthy
environment:
DB_HOST: db
DB_PORT: "5432"
DB_USER: app
DB_PASSWORD: app
DB_NAME: appdb
ports:
- "8000:8000"
volumes:
dbdata:
Step 2 — Do not get the database host wrong
The most common mistake is the app trying to reach the database at localhost. Inside Compose, localhost from the app container refers to the app container itself.
- Use the service name (above:
db) as the DB host, notlocalhost. - Use the port inside the DB container (5432), not the host-mapped port.
- Compose puts every service on a project network and provides DNS so service names resolve.
Step 3 — Start and check
docker compose up -d
docker compose ps # both services healthy/running?
docker compose logs -f web
Step 4 — Wait for the database at app startup
Right after docker compose up the database may still be starting, so the app can die first. Two ways to handle it:
- Use
depends_on: condition: service_healthyso the app starts after readiness (the example above) - Add retry logic in the app code (retry the connection a few times with a delay)
Common problems
Can't reach database server at localhost:5432→ change the host fromlocalhostto the service name.- DB env vars (POSTGRES_USER and so on) seem ignored → the container must be recreated. Use
docker compose up -d --force-recreateor wipe the volume. The official postgres image applies these variables only on first initialization. relation does not existin app logs → the DB is up but tables are not created yet. Run migrations.
Cleanup
docker compose down # remove containers/network (keep volumes)
docker compose down -v # also remove volumes (deletes DB data)
Sources
- Official docs Docker Compose docs — Compose v2
- GitHub postgres image env-var issue — POSTGRES_USER/DB behavior
- stackoverflow Connecting to Postgres inside a Compose stack — Use the service name, not localhost
Verified date indicates freshness. Check applicability conditions for older material.