Docker & Setup
Running PostgreSQL locally
Same as ClickHouse, everything here runs in Docker first. The image/container/volume model is identical across both modules — worth being precise about once.
From image to running server
A Docker image is a read-only template. A container is a running process created from that image, with its own writable layer on top. A volume is storage that lives outside the container's lifecycle, so data survives when the container is removed and recreated.
The image is pulled once and cached locally. Every
docker compose up after that reuses it — only the container is
created and destroyed. docker compose down removes the container
but leaves postgres_data untouched; only down -v deletes the
volume, and with it, every database in the cluster.
The compose file
This repo's postgres/compose.yaml is intentionally minimal — one
service, one port, one named volume:
services:
postgres:
image: postgres:17.6
ports:
- "5432:5432" # HOST : CONTAINER
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:Unlike ClickHouse's dual HTTP/native-protocol ports, Postgres exposes
a single port: 5432, the Postgres wire protocol. Every client —
psql, drivers, connection poolers — speaks it.
Environment & credentials
.env supplies the database name, user, and password Postgres
bootstraps on first start — first start only. Changing these after
the volume already has data does nothing until you wipe the volume,
because the role and database were already created on disk.
POSTGRES_DB=learning
POSTGRES_USER=admin
POSTGRES_PASSWORD=admin123The official Postgres image only runs its first-start initialization
scripts when /var/lib/postgresql/data is empty. If you change
.env after the volume already has data, nothing happens — the
admin role and learning database already exist from the first
run. Wipe the volume (docker compose down -v) to re-init.
Everyday commands
# start (detached)
docker compose up -d
# stop the container, keep the volume
docker compose stop
# remove the container, keep the volume
docker compose down
# remove container AND delete all data
docker compose down -v
# open a SQL shell inside the container
docker compose exec postgres psql -U admin -d learning
# tail logs
docker compose logs -f postgresVerifying it works
Once the container is up, connect and run a few sanity commands. The
first two are plain SQL; the last two are psql meta-commands
(client-side shortcuts, not SQL — they start with a backslash and
aren't sent to the server as queries):
SELECT version();
SELECT now();
\l -- list databases
\dt -- list tables in the current schemaWith the server running and reachable, the next lesson, Architecture, covers what's actually happening on the other end of that connection.