Ответ
Основной принцип — отделить данные от контейнера с помощью Docker Volumes или Bind Mounts. Контейнер должен быть эпиhemeral (временным), а данные — persistent (постоянными). В production-среде для Node.js приложений я всегда настраиваю том для данных СУБД.
Способ 1: Named Volumes (рекомендуется для Docker)
# docker-compose.yml для Node.js приложения и PostgreSQL
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: strongpassword
volumes:
- postgres_data:/var/lib/postgresql/data # Named volume
networks:
- app-network
app:
build: .
depends_on:
- postgres
environment:
DATABASE_URL: postgresql://user:strongpassword@postgres:5432/myapp
networks:
- app-network
volumes:
postgres_data: # Volume объявляется здесь
networks:
app-network:
driver: bridge
Способ 2: Bind Mounts (для разработки или специфичных путей на хосте)
volumes:
- ./postgres-data:/var/lib/postgresql/data
Ключевые практики для Node.js окружения:
- Используйте
.envфайлы или секреты Docker для хранения паролей БД, никогда не хардкодьте их. - Настройте регулярные бэкапы самого тома (например,
pg_dumpв cron-задаче внутри отдельного контейнера). - Для stateful-сервисов в оркестраторах (K8s) используйте PersistentVolumeClaims.
- Тестируйте процедуру восстановления из бэкапа на staging-окружении.
Почему это важно: При обновлении образа базы данных или перезапуске контейнера том с данными остается нетронутым. Удаление контейнера postgres не приведет к потере данных, так как они хранятся в volume postgres_data.