Skip to content
intermediate Phase 11 · Docker & Databases

PostgreSQL in Docker

Run and configure PostgreSQL containers with persistent storage.

1h
0 problems
Topic Progress 0%

Running with Persistent Storage

Running with Persistent Storage

Postgres keeps everything under one directory, so mounting that directory is non-negotiable:

docker run -d --name pg \
  -e POSTGRES_PASSWORD=devpass \
  -e POSTGRES_DB=app \
  -v pgdata:/var/lib/postgresql/data \
  -p 5432:5432 \
  postgres:16

The entrypoint initializes the cluster on first boot, creates the database, and starts the server on 5432. Pair it with a health check the orchestrator can consume:

docker exec pg pg_isready -U postgres

Without the named volume, docker rm destroys the cluster with the container — the classic way to lose a demo dataset.

Configuration for Containers

Configuration for Containers

Container Postgres shares RAM with the app, so defaults sized for a dedicated host are wrong. Override at launch or via a mounted config:

docker run -d --memory 2g postgres:16 \
  -c shared_buffers=512MB \
  -c max_connections=100 \
  -c effective_cache_size=1536MB

Common starting points: shared_buffers near a quarter of container memory, effective_cache_size describing what the OS cache is expected to contribute, and max_connections sized below what the pooler and memory allow — connection storms are better absorbed by PgBouncer than by raising the limit. Persist settings with -c flags or an postgresql.conf mount, never by exec-ing ALTER SYSTEM that no one can review.

Backups and Pitfalls

Backups and Pitfalls

Logical backups run inside the container:

docker exec pg pg_dump -U postgres -Fc app > app.dump
docker exec -i pg pg_restore -U postgres -d app_recovered < app.dump

-Fc (custom format) supports parallel restore and selective -t table recovery. Schedule it from the host, not from a container that dies with the cluster.

Pitfalls. Files in /docker-entrypoint-initdb.d run only when the data directory is empty — schema edits to them silently do nothing on a live volume. fsync=off speeds bulk loads but can corrupt after a hard stop: dev-only.

Interview: walk first-boot initialization, name the volume path you protect, and contrast pg_dump with physical base backups for point-in-time recovery.

Quiz

1. When do scripts in /docker-entrypoint-initdb.d execute?

Question 1 options

2. What does pg_isready tell an orchestrator?

Question 2 options

3. Why is raising max_connections often the wrong fix for load?

Question 3 options

Flashcards

Question

Data directory

Answer

/var/lib/postgresql/data — mount it to a named volume or data dies with the container.

Question

shared_buffers

Answer

Postgres's own cache, typically ~25% of container memory; effective_cache_size estimates the OS cache.

Question

pg_dump -Fc

Answer

Custom-format dump: compressed, parallel and table-selective restore.

Question

pg_isready

Answer

Connection probe used for health checks and service_healthy dependencies.

Revision Notes

Key Takeaways

  • 1. A named volume on /var/lib/postgresql/data is mandatory
  • 2. Size shared_buffers and max_connections to the container, not the host
  • 3. Init scripts run once, on an empty datadir only

Interview Tips

  • • Explain first boot: entrypoint → init scripts → permanent settings
  • • Contrast logical dump restore with physical backup/PITR and when each applies

Cheat Sheet

postgres:16 + -v pgdata:/var/lib/postgresql/data; -c shared_buffers ≈25% RAM; healthcheck pg_isready; pg_dump -Fc scheduled outside the container.

Continue Learning

Before You Start

  • No prerequisites listed.

Next Topics