Ответ
Частая проблема при запуске БД в Docker — потеря данных при пересоздании контейнера и проблемы с производительностью I/O. Сталкивался с этим при развертывании PostgreSQL.
Проблема: После docker-compose down и docker-compose up данные в базе обнулялись, так как том для данных не был настроен.
Решение: Использование Docker Volumes для сохранения данных и настройка производительности.
1. Корректный docker-compose.yml для PostgreSQL:
version: '3.8'
services:
postgres:
image: postgres:15-alpine
container_name: app_postgres
environment:
POSTGRES_DB: myapp
POSTGRES_USER: app_user
POSTGRES_PASSWORD: ${DB_PASSWORD} # Переменная из .env
ports:
- "5432:5432"
volumes:
# Постоянный том для данных
- postgres_data:/var/lib/postgresql/data
# Монтирование кастомных конфигов для тонкой настройки
- ./postgresql.conf:/etc/postgresql/postgresql.conf:ro
- ./init-scripts:/docker-entrypoint-initdb.d/
# Ограничение ресурсов и настройки производительности
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 1G
sysctls:
- kernel.shmmax=1073741824 # Увеличение shared memory для работы с большими буферами
command: >
postgres -c config_file=/etc/postgresql/postgresql.conf
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app_user -d myapp"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data: # Именованный том, которым управляет Docker
driver: local
2. Действия при проблеме "Database is uninitialized and superuser password is not specified": Эта ошибка возникает, если том уже содержит данные, но переменные окружения отличаются. Решение:
# 1. Останавливаем контейнер
docker-compose down
# 2. Делаем бэкап тома (на всякий случай)
docker run --rm -v app_postgres_data:/source -v $(pwd)/backup:/backup alpine tar czf /backup/postgres_backup.tar.gz -C /source .
# 3. Удаляем старый том (ВНИМАНИЕ: данные будут потеряны!)
docker volume rm app_postgres_data
# 4. Перезапускаем с чистыми данными
docker-compose up -d
3. Для продакшена: Я никогда не запускаю stateful-сервисы (БД) в Docker на продакшене напрямую. Вместо этого использую:
- Управляемые облачные сервисы (AWS RDS, Yandex Managed PostgreSQL).
- Операторы для Kubernetes (например, Zalando Postgres Operator), которые управляют репликацией, бэкапами и failover'ом.
- Если и запускаю в K8s, то только с StatefulSet и PersistentVolume, привязанным к сетевому хранилищу.