Перейти к содержимому

14. Базы данных в Docker

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

Окно терминала
# Запустить PostgreSQL
docker run -d \
--name postgres \
-e POSTGRES_DB=mydb \
-e POSTGRES_USER=myuser \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
-v postgres_data:/var/lib/postgresql/data \
postgres:15-alpine
# Подключиться к базе данных
docker exec -it postgres psql -U myuser -d mydb
# Выполнить SQL команду
docker exec -it postgres psql -U myuser -d mydb -c "SELECT version();"
# Дамп базы данных
docker exec postgres pg_dump -U myuser mydb > backup.sql
# Восстановление
docker exec -i postgres psql -U myuser mydb < backup.sql
Окно терминала
# Запустить MySQL 8
docker run -d \
--name mysql \
-e MYSQL_ROOT_PASSWORD=rootsecret \
-e MYSQL_DATABASE=mydb \
-e MYSQL_USER=myuser \
-e MYSQL_PASSWORD=secret \
-p 3306:3306 \
-v mysql_data:/var/lib/mysql \
mysql:8.0
# Подключиться
docker exec -it mysql mysql -u myuser -psecret mydb
# Дамп
docker exec mysql mysqldump -u myuser -psecret mydb > backup.sql
Окно терминала
# Запустить Redis с персистентностью
docker run -d \
--name redis \
-p 6379:6379 \
-v redis_data:/data \
redis:7-alpine \
redis-server --appendonly yes --requirepass "redissecret"
# Подключиться через redis-cli
docker exec -it redis redis-cli -a redissecret
# Проверить работу
docker exec -it redis redis-cli ping # → PONG
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: ${POSTGRES_DB:-mydb}
POSTGRES_USER: ${POSTGRES_USER:-user}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secret}
ports:
- "${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-user} -d ${POSTGRES_DB:-mydb}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
restart: unless-stopped
redis:
image: redis:7-alpine
command: redis-server --requirepass ${REDIS_PASSWORD:-redissecret} --appendonly yes
ports:
- "${REDIS_PORT:-6379}:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-redissecret}", "ping"]
interval: 10s
timeout: 5s
retries: 3
restart: unless-stopped
pgadmin:
image: dpage/pgadmin4:latest
environment:
PGADMIN_DEFAULT_EMAIL: [email protected]
PGADMIN_DEFAULT_PASSWORD: admin
ports:
- "5050:80"
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
redis_data:

Healthcheck позволяет Docker знать, когда база данных готова принимать запросы:

# В Dockerfile PostgreSQL
HEALTHCHECK --interval=10s --timeout=5s --retries=5 \
CMD pg_isready -U $POSTGRES_USER -d $POSTGRES_DB
# Проверить healthcheck
docker inspect --format='{{.State.Health.Status}}' postgres
# healthy | unhealthy | starting
services:
postgres:
image: postgres:15-alpine # Alpine для меньшего размера
restart: unless-stopped # автоперезапуск
shm_size: '256mb' # shared memory для PostgreSQL
security_opt:
- no-new-privileges:true # безопасность
read_only: false # БД нужна запись
tmpfs:
- /tmp # временные файлы в RAM
ulimits:
nofile:
soft: 65536
hard: 65536