Docker Compose с PostgreSQL: готовый docker-compose.yml
Готовый docker-compose.yml для PostgreSQL: данные хранятся в именованном томе, пароль берётся из файла .env, а healthcheck сообщает, когда база готова принимать подключения. Файл проверен на PostgreSQL 16.
docker-compose.yml
services:
db:
image: postgres:16
container_name: app-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER:-app}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Укажите POSTGRES_PASSWORD в файле .env}
POSTGRES_DB: ${POSTGRES_DB:-app}
ports:
- "127.0.0.1:5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
- ./initdb:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 3s
retries: 10
volumes:
pgdata:Файл .env рядом с docker-compose.yml
POSTGRES_USER=app
POSTGRES_PASSWORD=замените-на-длинный-случайный-пароль
POSTGRES_DB=appНе добавляйте .env в git: внесите его в .gitignore.
Что делает каждая настройка
Настройка | Зачем нужна |
|---|---|
| Фиксирует мажорную версию. Тег |
| Обязательная переменная: без неё контейнер не запустится |
| Порт доступен только с вашей машины, а не из сети |
| Именованный том: данные переживают пересоздание контейнера |
|
|
| Позволяет другим сервисам дождаться готовности базы |
| Двойной |
Запуск и работа с базой
docker compose up -d # запустить в фоне
docker compose ps # статус и health: healthy
docker compose logs -f db # логи
docker compose exec db psql -U app -d app # консоль psql внутри контейнера
docker compose down # остановить, данные сохранятсяПодключение приложения
С хоста строка подключения выглядит так:
postgresql://app:ПАРОЛЬ@localhost:5432/appЕсли приложение запущено в том же compose-файле, обращайтесь по имени сервиса, а не к localhost. Чтобы приложение стартовало после готовности базы, добавьте depends_on:
services:
api:
build: .
environment:
DATABASE_URL: postgresql://app:${POSTGRES_PASSWORD}@db:5432/app
depends_on:
db:
condition: service_healthyРезервная копия и восстановление
# сохранить дамп
docker compose exec -T db pg_dump -U app -d app > backup.sql
# восстановить в пустую базу
docker compose exec -T db psql -U app -d app < backup.sqlЧастые проблемы
Скрипты из initdb не выполняются
Файлы из docker-entrypoint-initdb.d запускаются только при инициализации пустого каталога данных. Если том уже существует, они игнорируются. Для повторного запуска удалите том командой docker compose down -v, но помните, что данные будут потеряны.
Ошибка «password authentication failed»
Пароль из POSTGRES_PASSWORD применяется только при создании тома. Если вы изменили пароль в .env позже, он не обновится в существующей базе. Смените его командой ALTER USER app PASSWORD 'новый-пароль'; или пересоздайте том.
Порт 5432 уже занят
На машине уже запущен другой PostgreSQL. Измените внешний порт: "127.0.0.1:5433:5432", и подключайтесь к 5433.
Как обновиться на другую мажорную версию
Простая смена тега, например с 16 на 17, не сработает: формат данных различается между мажорными версиями. Сделайте pg_dump, запустите новую версию на пустом томе и восстановите дамп.