ЯдроКодаподготовка к экзаменам
Учебная платформа

Загружаем материалы

Подготавливаем материалы и навигацию по разделу.

PostgreSQL в Docker Compose: запуск, healthcheck и сохранение базы

Автор: · Обновлено

Соберём локальный PostgreSQL для разработки: база запускается через Compose, данные переживают пересоздание, готовность видна в статусе, а порт доступен только на компьютере…

Соберём локальный PostgreSQL для разработки: база запускается через Compose, данные переживают пересоздание, готовность видна в статусе, а порт доступен только на компьютере разработчика. Пример намеренно использует PostgreSQL 17: это делает путь данных явным и позволяет отдельно объяснить изменения официального образа в версии 18.

Полный Compose-файл

В новой папке создайте compose.yaml. Пароль ниже учебный, для одноразового локального стенда; не используйте его на сервере и не копируйте реальные секреты в Git.

name: yk-postgres-demo
services:
  db:
    image: postgres:17-alpine
    environment:
      POSTGRES_USER: learner
      POSTGRES_PASSWORD: local-demo-only
      POSTGRES_DB: lessons
    ports:
      - "127.0.0.1:15432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -h 127.0.0.1 -U \"$$POSTGRES_USER\" -d \"$$POSTGRES_DB\""]
      interval: 5s
      timeout: 3s
      retries: 10
      start_period: 10s
volumes:
  pgdata:

Пара $$ сохраняет доллар для shell внутри контейнера: переменные раскрывает healthcheck, а не Compose на хосте. pg_isready проверяет, принимает ли сервер соединения; успешный результат не доказывает наличие нужной таблицы или корректность пароля прикладного пользователя. Для этого нужен отдельный SQL-запрос. Коды pg_isready.

Создать и прочитать запись

docker compose config -q
docker compose up -d --wait --wait-timeout 90
docker compose ps
docker compose exec -T db psql -U learner -d lessons -v ON_ERROR_STOP=1 -c "CREATE TABLE IF NOT EXISTS notes (id integer PRIMARY KEY, body text NOT NULL); INSERT INTO notes VALUES (1, 'persisted') ON CONFLICT (id) DO NOTHING;"
docker compose exec -T db psql -U learner -d lessons -Atc "SELECT body FROM notes WHERE id=1;"

Ожидается persisted. Теперь выполните docker compose up -d --force-recreate --wait db и повторите SELECT: запись остаётся, потому что новый контейнер использует тот же named volume. При отсутствии опции --wait в старом установленном Compose дождитесь healthy через docker compose ps, не заменяйте проверку произвольным коротким sleep.

Из IDE на хосте подключайтесь к 127.0.0.1:15432, а из соседнего сервиса этого проекта — к db:5432. Пользователь learner, база lessons; в учебном официальном образе POSTGRES_USER создаёт привилегированного пользователя инициализации. Для рабочего приложения подготовьте отдельную роль с необходимыми правами.

Почему новый пароль не применился

Переменные и скрипты /docker-entrypoint-initdb.d участвуют в начальной подготовке пустого каталога данных. Изменение POSTGRES_PASSWORD при сохранённом томе не переустанавливает пароль существующей роли. Если возник отказ аутентификации после правки YAML, проверьте, создаёте ли вы новую базу или подключаете прежнюю. Штатно измените роль средствами PostgreSQL; не удаляйте том с пользовательскими данными ради применения переменной. Правила официального образа.

Для 18 и новее стандартный mount-target официального образа изменён на /var/lib/postgresql, а PGDATA размещается в каталоге major-версии, например /var/lib/postgresql/18/docker. Нельзя просто заменить тег 17 на 18 и предположить совместимость старого каталога. Обновление major требует процедуры PostgreSQL, проверки расширений и восстановления/pg_upgrade.

Готовность зависимого приложения

Обычный depends_on: [db] задаёт порядок запуска, а не готовность SQL. Условие service_healthy позволяет дождаться healthcheck при старте зависимого сервиса. Оно не наблюдает каждое дальнейшее соединение и не лечит недоступную базу автоматически: приложение всё равно должно корректно обрабатывать обрыв. Startup order.

Практическая проверка

Пересоздайте контейнер, убедитесь в сохранности строки, затем сделайте логический дамп и проверьте его восстановление в отдельной базе по уроку PostgreSQL о резервных копиях. После работы docker compose down остановит стенд без удаления данных. down -v допустим только когда этот учебный том действительно больше не нужен. Зафиксируйте имя тома и версию PostgreSQL рядом с инструкциями проекта: это важнее воспроизведения одной удачной команды запуска.

Источники