Skip to content
Commitpedia
Log in Join & edit

docker compose for an app with a PostgreSQL database

A compose.yaml that runs your application next to a PostgreSQL container, with a named volume for the data, a health check so the app starts after the database is ready, and the commands to operate it.

Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?

Edit history of docker compose for an app with a PostgreSQL database: 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
3 min

Docker Compose describes several containers in one YAML file and starts, stops and rebuilds them together. The most common pair is an application plus a database. This entry walks through a compose.yaml for an app and PostgreSQL, explaining each part, and then the day-to-day commands. Compose ships as the docker compose plugin with Docker Engine and Docker Desktop; the old separate docker-compose binary is retired.

The compose file

Save this as compose.yaml in the project directory, next to the app’s Dockerfile:

services:
  app:
    build: .
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgres://app:app_password@db:5432/app
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

  db:
    image: postgres:17
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app_password
      POSTGRES_DB: app
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 3s
      retries: 10
    restart: unless-stopped

volumes:
  pgdata:

What each part does

  • services: one entry per container. Compose puts them on a shared network where each service is reachable by its name, so the app connects to host db, port 5432, and no port needs to be published for the database.
  • build: . builds the app image from the Dockerfile in this directory. Use image: instead when the image already exists in a registry.
  • ports publishes the app on localhost:8000. Quote port mappings; unquoted 8000:8000 can be misread by YAML.
  • environment passes configuration in. The PostgreSQL image reads POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DB on first start to create the user and database.
  • volumes: pgdata:/var/lib/postgresql/data stores the database files in a named volume, so docker compose down and up keep the data. The volume is declared at the bottom.
  • healthcheck runs pg_isready every 5 seconds. Combined with depends_on: condition: service_healthy it makes the app wait until PostgreSQL accepts connections, not merely until the container exists.
  • restart: unless-stopped brings both back after a reboot or crash.

The example pins postgres:17. Pin a major version for databases: moving to a newer major requires a dump and restore, and from PostgreSQL 18 the official image also changed its default data directory, so an unpinned latest can break on the next pull.

Keep secrets out of the file

Compose reads a .env file in the same directory and substitutes ${VAR} in the YAML. Put the password there and keep .env out of version control:

POSTGRES_PASSWORD=choose-a-long-random-password
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

Run docker compose config to see the file with all variables filled in and check that it parses.

Start, inspect, stop

docker compose up -d
docker compose ps
docker compose logs -f db
docker compose logs -f app
docker compose exec db psql -U app -d app
docker compose stop
docker compose down
  • up -d builds what is missing, creates the network and volume, and starts both services in the background.
  • exec db psql ... opens a SQL shell inside the database container; \dt lists tables, \q leaves.
  • stop stops the containers but keeps them; down removes containers and the network but keeps the named volume.
  • Careful: docker compose down -v also deletes the pgdata volume and with it the whole database.

Rebuild after code changes

docker compose up -d --build app
docker compose pull db
docker compose up -d

--build rebuilds the app image before starting. pull fetches a newer postgres:17 minor release, which is safe to apply with a plain up -d.

Back up the database

docker compose exec db pg_dump -U app -d app > backup.sql
cat backup.sql | docker compose exec -T db psql -U app -d app

The first line writes a plain SQL dump to the host. The second restores it into an empty database; -T disables the pseudo-terminal so the file can be piped in.

Official documentation

Did this work for you?

No votes yet. Be the first.

If it did not work, the report form below tells the editors what went wrong.

See also

  • 0056 Docker Compose: run a small web app with a database Docker Compose describes several containers, their ports, volumes and environment in one compose.yaml file, then starts them all with docker compose up. Intermediate · Step by step · Linux, macOS, Windows Article Docker basics · Docker Compose 15 Oct 2026
  • 0198 Install PostgreSQL and connect with psql on Debian, Ubuntu and RHEL Install the PostgreSQL server from your distribution or the official PGDG repositories, start it, and open your first psql session as the… Beginner · Step by step · Linux Article Install & connect 15 Oct 2026
  • 0199 psql meta-commands cheat sheet The backslash commands you use every day in psql: connecting, listing databases, tables and roles, describing objects, timing queries, expanded output and… Beginner · Cheat sheet · Any system Article Install & connect · Roles & administration 15 Oct 2026
  • 0201 pg_hba.conf and PostgreSQL authentication methods pg_hba.conf decides who may connect from where and how they must prove who they are. Rules are checked top to bottom and… Intermediate · Explains an idea · Linux Article Install & connect · Security & access 15 Oct 2026
  • 0210 Fix: FATAL: no pg_hba.conf entry for host The server received the connection but no pg_hba.conf rule matches this client address, user, database and SSL mode. Add or correct a… Intermediate · Fixes an error · Linux Article Install & connect · Security & access 15 Oct 2026
  • 0211 Fix: psql connection to server on socket /var/run/postgresql/.s.PGSQL.5432 failed psql tried the local Unix socket and found nothing there. The server is not running, listens on another port, or uses a… Beginner · Fixes an error · Linux Article Install & connect 15 Oct 2026

Repos in the wild

  • postgres/postgres: PostgreSQL source code mirror postgres/postgres The official read-only GitHub mirror of the PostgreSQL source repository. Browse the code and history here; patches go through the project's mailing lists, not pull requests. GitHub
  • docker/compose docker/compose The source of Docker Compose, the tool that defines and runs multi-container applications from a compose.yaml file. Useful for release notes, the issue tracker and the examples directory. GitHub
  • Traefik: a reverse proxy that configures itself from Docker and Kubernetes traefik/traefik Traefik is an open-source edge router that discovers services from Docker labels, Kubernetes resources and other providers and routes traffic to them, with automatic Let's Encrypt certificates and a dashboard. GitHub

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Dominik +4,198 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?