Перейти к основному содержимому

PostgreSQL в Docker

Инженеру

Раздел 8.11, шаг 7 из 12. Дальше — облако и Kubernetes.


Базовый запуск

Официальный образ — hub.docker.com/_/postgres.

docker run -d \
--name pg-dev \
-e POSTGRES_USER=app \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=appdb \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:16-alpine
ПеременнаяСмысл
POSTGRES_USER / POSTGRES_PASSWORDСуперпользователь (default postgres)
POSTGRES_DBБД, создаваемая при init
PGDATAПуть к данным внутри контейнера (default /var/lib/postgresql/data)

Init-скрипты — монтируйте .sql / .sh в /docker-entrypoint-initdb.d/ (выполняются только при первом создании volume).


Volume — обязательное правило

Без named volume или bind-mount данные исчезают при удалении контейнера.

Код ITЗагрузка примера кода…

healthcheck с pg_isready — приложение должно ждать depends_on: condition: service_healthy (Compose v2+). Разбор готовых стеков "только Postgres" и "app + db" — Docker Compose — готовые стеки (№3 и №4).


Сеть и несколько контейнеров

Код ITЗагрузка примера кода…

Имя сервиса db — DNS внутри compose-сети. Приложение подключается к PgBouncer, Postgres остаётся internal.


Кастомный конфиг

Вариант 1 — command: postgres -c key=val (см. выше).

Вариант 2 — смонтировать файл:

volumes:
- ./postgresql.conf:/etc/postgresql/postgresql.conf:ro
command: postgres -c config_file=/etc/postgresql/postgresql.conf

На production в контейнере часто минимальный конфиг + override через orchestrator.


Типовые ошибки

ОшибкаПоследствиеРешение
Данные в writable layerПотеря при recreateNamed volume
docker-compose down -v в CIУдаление volumeОтдельный volume для prod
Один контейнер = prod БД без бэкапаПотеря данныхшаг 10, managed или Patroni
fsync=off "для скорости"Корruption при crashТолько ephemeral dev
Root в контейнере + широкие права на volumeРиск безопасностиUser namespace, POSTGRES_INITDB_ARGS=--auth-host=scram-sha-256
Контейнер ≠ высокая доступность

Один Docker-контейнер с Postgres подходит для dev/stage и учебных стендов. Production HA — репликация, Patroni или managed-сервис (шаги 8–9).


Образы и версии

  • -alpine — меньше размер, иногда проблемы с локалями и расширениями.
  • Pinningpostgres:16.4-alpine, не latest.
  • Расширения (PostGIS) — образы postgis/postgis или сборка своего Dockerfile:
FROM postgres:16-alpine
RUN apk add --no-cache postgis

Миграция данных в/из контейнера

docker exec -t pg-dev pg_dump -U app -Fc appdb > backup.dump
docker exec -i pg-dev pg_restore -U app -d appdb < backup.dump

Логический dump переносим между версиями (с оговорками major upgrade).


Практика

  1. Поднимите compose с api + postgres + healthcheck; подключитесь через phpPgAdmin или psql.
  2. Убейте контейнер db, пересоздайте — данные должны сохраниться в volume.
  3. Добавьте PgBouncer, прогоните нагрузку через pgbench на 6432.

Связанные материалы