Гид по технологиям

PostgreSQL в Docker: запуск, настройка и практики для разработки и продакшена

8 min read Databases Обновлено 01 Dec 2025
PostgreSQL в Docker — запуск и лучшие практики
PostgreSQL в Docker — запуск и лучшие практики

Иллюстрация: логотипы Docker и PostgreSQL

PostgreSQL можно удобно запускать в контейнере Docker для локальной разработки и тестирования: используйте официальный образ, сохраняйте данные в томах, инициализируйте базу через /docker-entrypoint-initdb.d и подключайте приложения через Docker-сеть. Для продакшена оцените требования к производительности, резервному копированию и управлению секретами прежде чем контейнеризировать базу.

Быстрые ссылки

  • Getting Started
  • Connecting to Your Database
  • Configuring PostgreSQL
  • Seeding the Database
  • Creating a Custom Database Image
  • Should You Containerize Your Production Database?
  • Итоги

Кому полезно это руководство

Коротко: разработчикам, инженерам DevOps, администраторам БД и тестировщикам, которым нужно быстро поднять PostgreSQL в контейнере или понять подводные камни при переходе на контейнеры в продакшене.

Определения в одну строку:

  • Docker volume — устойчивое хранилище данных вне контейнера.
  • Docker network — логическая сеть для связи контейнеров на хосте.

Введение

PostgreSQL (Postgres) — мощная объектно-реляционная СУБД с богатой поддержкой SQL и расширениями для работы со сложными данными. В типичной архитектуре СУБД запускается отдельно от кода приложения, поэтому контейнеризация помогает изолировать сервер базы данных и упростить развёртывание для разработчиков.

В этом руководстве описаны базовые шаги по запуску PostgreSQL в Docker, способы инициализации данных, примеры кастомизации конфигурации, рекомендации по безопасности и надежности, а также сценарии, в которых контейнеризация подходит или не подходит.

Getting Started

Официальный образ PostgreSQL доступен на Docker Hub и имеет теги для разных версий и базовых образов (Alpine, Debian Stretch, Debian Bullseye и др.). В примерах используется тег

postgres:14

который даёт PostgreSQL 14 на базе Debian Bullseye. Можно выбирать другие версии по потребностям.

Запуск контейнера прост: пример базовой команды для локальной разработки приведён ниже. Обратите внимание, что переменная окружения POSTGRES_PASSWORD обязательна.

docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD= \
  -v postgres:/var/lib/postgresql/data \
  postgres:14

Пояснения:

  • POSTGRES_PASSWORD задаёт пароль суперпользователя postgres (можно изменить имя через POSTGRES_USER).
  • -v postgres:/var/lib/postgresql/data создаёт именованный volume postgres и монтирует его в каталог данных PostgreSQL; это предотвращает потерю данных при пересоздании контейнера.
  • -p 5432:5432 пробрасывает порт контейнера на хост. Для контейнеров в одной сети проброс порта не обязателен.
  • -d запускает контейнер в фоновом режиме.

Важно: никогда не храните пароли в коммитах репозитория. Используйте секреты или файлы, когда это возможно.

Supplying the Password as a File

Если не хотите передавать пароль в командной строке, можно использовать файл и переменную POSTGRES_PASSWORD_FILE. Пример с Docker bind mount:

docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-password \
  -v ./postgres-password.txt:/run/secrets/postgres-password \
  -v postgres:/var/lib/postgresql/data \
  postgres:14

Эта техника применима и к другим поддерживаемым переменным окружения, например POSTGRES_USER. В продакшене вместо bind mount используйте механизм секретов оркестратора (Docker Swarm, Kubernetes Secrets) или менеджер секретов.

Connecting to Your Database

После привязки порта 5432 к localhost вы можете подключиться к базе с хоста по адресу localhost:5432 используемыми при запуске учетными данными.

В образе есть утилита psql. Чтобы открыть интерактивную сессию внутри контейнера, выполните:

docker exec -it postgres psql -U postgres

Для автоматизированных сценариев предпочтительнее использовать клиентские библиотеки (JDBC, libpq, psycopg) и переменные окружения.

Connecting From Other Docker Containers

Лучше не пробрасывать порт на хост, если клиентом является другой контейнер. Создайте Docker-сеть и подключите к ней оба контейнера.

Создание сети:

docker network create my-app

Запуск Postgres в сети:

docker run -d \
  --name postgres \
  --network my-app \
  -e POSTGRES_PASSWORD= \
  -v postgres:/var/lib/postgresql/data \
  postgres:14

Запуск приложения в той же сети:

docker run -d \
  --name api \
  --network my-app \
  my-api:latest

Контейнеры внутри сети могут обращаться к Postgres по хостнейму postgres и порту 5432.

Конфигурирование PostgreSQL

Параметры сервера можно передать через -c после имени образа — всё, что идёт после тега образа, передаётся в команду, запускаемую в контейнере (в случае образа Postgres это бинарник сервера):

docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD= \
  -v postgres:/var/lib/postgresql/data \
  postgres:14 -c max_connections=100

Если нужно задать много параметров, удобнее монтировать собственный конфигурационный файл и передать путь через config_file:

docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD= \
  -v ./postgres.conf:/etc/postgresql/postgresql.conf \
  -v postgres:/var/lib/postgresql/data \
  postgres:14 -c config_file=/etc/postgresql/postgresql.conf

Пример структуры postgres.conf можно взять в официальной документации PostgreSQL. При монтировании конфигурации учитывайте права доступа и владельца файла.

Seeding the Database

Официальный образ выполняет инициализационные сценарии, размещённые в /docker-entrypoint-initdb.d. Любые .sql, .sql.gz или .sh файлы будут выполнены при создании пустой директории данных (т.е. при первом запуске с новым volume).

Пример монтирования набора скриптов:

docker run -d \
  --name postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD= \
  -v ./db-seed-files/:/etc/docker-entrypoint-initdb.d \
  -v postgres:/var/lib/postgresql/data \
  postgres:14

Скрипты выполняются в алфавитном порядке — удобный трюк для последовательной инициализации: префиксуйте имена файлов порядковыми номерами.

Creating a Custom Database Image

Чтобы инкапсулировать конфигурацию и инициализаторы в образе, можно создать Dockerfile:

FROM postgres:14

COPY postgres.conf /etc/postgresql/postgresql.conf
COPY db-seed-files/ /etc/docker-entrypoint-initdb.d/

CMD ["-c", "config_file=/etc/postgresql/postgresql.conf"]

Сборка и запуск:

docker build -t custom-postgres:latest .

docker run -d \
  --name custom-postgres \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD= \
  -v postgres:/var/lib/postgresql/data \
  custom-postgres:latest

Кастомные образы упрощают воспроизводимость окружений для команды разработчиков, но требуют соблюдения практик безопасности (удаление секретов из образа, сканирование уязвимостей и т.д.).

Пример docker-compose для разработки

Ниже — удобный шаблон docker-compose.yml для локальной разработки. Он демонстрирует named volume, сеть и простой healthcheck.

version: '3.8'

services:
  db:
    image: postgres:14
    container_name: postgres
    environment:
      POSTGRES_USER: devuser
      POSTGRES_PASSWORD_FILE: /run/secrets/postgres-password
      POSTGRES_DB: devdb
    volumes:
      - db-data:/var/lib/postgresql/data
      - ./db-init:/docker-entrypoint-initdb.d:ro
    networks:
      - app-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U devuser -d devdb"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  db-data:

networks:
  app-network:
    driver: bridge

Для секретов в Compose можно использовать secrets секцию или внешние менеджеры секретов.

Резервное копирование и восстановление

Регулярные бэкапы критичны. Для логического дампа используйте pg_dump/pg_dumpall. Примеры:

  • Снять дамп базы из контейнера:
docker exec -t postgres pg_dump -U postgres mydb > mydb.sql
  • Восстановить дамп в контейнере:
docker exec -i postgres psql -U postgres -d mydb < mydb.sql

Для больших БД логическое резервное копирование не всегда удобно; рассмотрите физическое резервирование (pg_basebackup) и репликацию.

Мониторинг и готовность

Наблюдаемость помогает вовремя заметить проблемы:

  • Используйте встроенные представления PostgreSQL (pg_stat_activity, pg_stat_database) для мониторинга соединений и запросов.
  • Настройте метрики через экспортёры (например, postgres_exporter) и собирайте их в системе мониторинга (Prometheus/Grafana).
  • Healthchecks в контейнерах должны проверять readiness: pg_isready или выполнение простого SQL.

Безопасность и управление секретами

Рекомендации:

  • Храните пароли в менеджере секретов, а не в Dockerfile или репозитории.
  • Ограничьте доступ к объёму данных и файлам конфигурации.
  • Используйте TLS для клиентских соединений, если трафик идёт через ненадёжные сети.
  • Обновляйте образы и применяйте патчи безопасности.

Производительность и ограничения

Контейнеры дают небольшую накладную на производительность. Перед решением о деплойменте в продакшен проверьте:

  • Накладные расходы ввода-вывода на используемой файловой системе и драйвере Docker (overlayfs, aufs и т.д.).
  • Поведение при высокой нагрузке и долгих транзакциях.
  • Потребности в I/O, CPU и памяти — настройте параметры Postgres (work_mem, shared_buffers, maintenance_work_mem) в соответствии с ресурсами.

Если база будет обрабатывать очень большие объёмы данных или требует низкой латентности, взвесьте использование управляемого сервиса СУБД или выделенных виртуальных машин.

Репликация и отказоустойчивость

Организация репликации в контейнерной среде возможна, но требует продуманной инфраструктуры для хранения WAL, настройки реплик и failover. В простых случаях можно использовать встроенные механизмы PostgreSQL (streaming replication) и сторонние инструменты для failover.

Когда контейнеризация не подходит

Контейнеризация PostgreSQL может не подходить в случаях:

  • Требуется экстремально высокая производительность и минимальная латентность.
  • Организация хранения данных накладывает ограничения (например, специфичные SAN-решения, аппаратные RAID).
  • Уже используется управляемый сервис СУБД, предоставляющий SLA и резервирование.

В этих ситуациях эффективнее выбрать специализированное решение вне контейнеров.

Практические чеклисты

Чеклист для разработчика

  • Использую volume для хранения данных
  • Не храню пароли в репозитории
  • Скрипты инициализации находятся в /docker-entrypoint-initdb.d
  • Тесты запускают базу и очищают её после использования

Чеклист для оператора

  • Настроены бэкапы и планы восстановления
  • Есть мониторинг и алерты на ключевые метрики
  • Секреты хранятся в менеджере секретов
  • План миграции/откатов для обновления образов

Чеклист для QA

  • Подготовлены тестовые данные и сценарии загрузки
  • Проверены backup/restore сценарии
  • Проверены пиковые нагрузки и поведение при нехватке ресурсов

Инцидентный план и откат

Краткий порядок действий при проблемах с контейнерной БД:

  1. Оценить доступность volume и целостность данных.
  2. Если контейнер остановлен, попытаться рестартовать сервис: docker start/stop.
  3. При невозможности рестарта — запустить временный контейнер с подключением к тому же volume и выполнить диагностику.
  4. Развернуть восстановление из свежего бэкапа на отдельном экземпляре и сверить данные.
  5. После восстановления провести тесты целостности и переключить приложения на новый экземпляр.

Важно: заранее прогоняйте процедуру восстановления, чтобы она была проверенной.

Тест-кейсы и критерии приёмки

Тест-кейсы:

  • Запуск контейнера с пустым volume приводит к выполнению инициализационных скриптов.
  • Перезапуск контейнера без удаления volume не теряет данных.
  • Подключение приложений по сети my-app успешно проходит.
  • Бэкап и восстановление с использованием pg_dump/pg_restore возвращает данные корректно.

Критерии приёмки:

  • Система проходит базовые тесты интеграции и нагрузочные тесты в пределах допустимой латентности.
  • Наличие валидного плана резервного копирования и восстановления.
  • Секреты не находятся в репозитории и защищены менеджером секретов.

Альтернативные подходы

  • Управляемые облачные сервисы (RDS, Cloud SQL) — меньше усилий по эксплуатации, SLA и автоматические бэкапы.
  • Виртуальные машины с EBS/NFS/SAN — полезно, если нужны тонкие настройки хранения.
  • Kubernetes с StatefulSet — хорош для масштабирования и автоматизации, но требует навыков оператора.

Модели мышления и эвристики

  • «Если база нужна только для локальной разработки» — контейнеризация почти всегда оправдана.
  • «Если нужна долговременная надёжность и производительность» — сначала протестируйте контейнерный подход и сравните с альтернативами.
  • Всегда отделяйте состояние (volume) от образа.

Советы по миграции и совместимости

  • Перед обновлением версии PostgreSQL выполните тестовые миграции на копии данных.
  • Проводите миграции в контролируемой среде и имейте план отката.
  • Убедитесь, что используемые расширения совместимы с новой версией сервера.

Security hardening

  • Ограничьте сетевой доступ к базе через брандмауэр или политику сети контейнеров.
  • Применяйте только необходимые привилегии пользователям и ролям.
  • Регулярно обновляйте образы и следите за уязвимостями.

Примеры сценариев отказа и обходные пути

  • Образ повреждён: используйте другой тег образа и монтируйте старый volume.
  • Volume недоступен: проверьте права доступа и состояние хоста; восстановите из бэкапа при необходимости.
  • Некорректные init скрипты: тестируйте скрипты локально и используйте порядковые префиксы для контроля порядка выполнения.

Резюме

Контейнеризация PostgreSQL — удобный инструмент для разработчиков и команд, которые хотят упростить воспроизводимость сред. Для продакшен-использования требуется дополнительное внимание к резервному копированию, мониторингу, безопасности и производительности. Всегда храните данные вне контейнера, управляйте секретами централизованно и прогоняйте сценарии восстановления заранее.

Важное

  • Обязательно используйте volume для данных, чтобы избежать потери информации при пересоздании контейнеров.
  • Для контейнеров в одной сети избегайте проброса портов на хост, если это не требуется.

Дополнительные ресурсы

  • Официальная документация PostgreSQL — используйте её как справочник по параметрам конфигурации и возможностям.
  • Документация Docker — для деталей по томам, сетям и секретам.

Короткое итоговое напоминание: контейнеры удобны и ускоряют разработку, но критические для бизнеса базы требуют продуманной стратегии обеспечения устойчивости и безопасности.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство