Korean

Run a Web App and Database Together with Docker Compose

Procedures / docker-webapp-db.html

proceduresEnv: Docker 24+, Docker Compose v2, PostgreSQL 16Verified: 2026-10-19

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, not localhost.
  • 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_healthy so 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 from localhost to the service name.
  • DB env vars (POSTGRES_USER and so on) seem ignored → the container must be recreated. Use docker compose up -d --force-recreate or wipe the volume. The official postgres image applies these variables only on first initialization.
  • relation does not exist in 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

Verified date indicates freshness. Check applicability conditions for older material.