← Назад к вопросам

Что должно быть указано в конфигурации Docker Compose?

1.0 Junior🔥 121 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Docker Compose конфигурация: что должно быть указано

Docker Compose — это инструмент для описания и запуска мультиконтейнерных приложений. Хорошая конфигурация — это ключ к воспроизводимой разработке и гладкому переходу на production.

Минимальная валидная конфигурация

version: '3.8'

services:
  app:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
    depends_on:
      - db
  
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Детальная структура Docker Compose

1. Версия

version: '3.8'  # Используй 3.8 для современного синтаксиса

Разные версии поддерживают разные возможности. 3.8 совместима с Docker Engine 19.03+

2. Services (основное содержимое)

services:
  app:  # Название сервиса
    # Конфигурация приложения
  
  database:
    # Конфигурация БД
  
  cache:
    # Конфигурация кэша

Полный пример с производственными практиками

version: '3.8'

services:
  # === WEB APPLICATION ===
  app:
    # 1. Способ получения образа
    build:
      context: .              # Путь к Dockerfile
      dockerfile: Dockerfile  # Имя файла (опционально)
      args:
        - BUILD_ENV=production
    
    # 2. Имя образа
    image: myapp:latest
    
    # 3. Имя контейнера
    container_name: myapp-container
    
    # 4. Порты (host:container)
    ports:
      - "8000:8000"      # FastAPI/Django приложение
      - "8001:8001"      # Дополнительный сервис (опционально)
    
    # 5. Environment переменные
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
      - REDIS_URL=redis://cache:6379/0
      - DEBUG=false
      - LOG_LEVEL=info
      - SECRET_KEY=${SECRET_KEY}  # Из .env файла
    
    # 6. Альтернатива: env_file
    # env_file:
    #   - .env
    #   - .env.production
    
    # 7. Volumes (для разработки и данных)
    volumes:
      - .:/app              # Current directory в контейнер (dev)
      - /app/__pycache__    # Исключаем __pycache__
      - app_logs:/app/logs  # Логи в named volume
    
    # 8. Working directory в контейнере
    working_dir: /app
    
    # 9. Команда для запуска
    command: python -m uvicorn main:app --host 0.0.0.0 --port 8000 --reload
    
    # 10. Зависимости (порядок запуска)
    depends_on:
      db:
        condition: service_healthy  # Ждём пока БД будет готова
      cache:
        condition: service_started    # Ждём просто старта
    
    # 11. Лимиты ресурсов
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
    
    # 12. Политика перезапуска
    restart_policy:
      condition: on-failure
      max_attempts: 3
      delay: 5s
    
    # 13. Health check (для depends_on)
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s
    
    # 14. Networks (для общения между контейнерами)
    networks:
      - app-network
  
  # === DATABASE ===
  db:
    image: postgres:15-alpine
    container_name: myapp-db
    
    environment:
      POSTGRES_USER: dbuser
      POSTGRES_PASSWORD: ${DB_PASSWORD}  # Из .env
      POSTGRES_DB: myapp
      POSTGRES_INITDB_ARGS: "--encoding=UTF8 --locale=C"
    
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init-db.sql:/docker-entrypoint-initdb.d/init.sql  # Инициализация БД
    
    ports:
      - "5432:5432"  # Для локального подключения (опционально)
    
    networks:
      - app-network
    
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U dbuser"]
      interval: 10s
      timeout: 5s
      retries: 5
    
    # Параметры для production
    command:
      - "postgres"
      - "-c"
      - "shared_buffers=256MB"
      - "-c"
      - "max_connections=100"
  
  # === REDIS CACHE ===
  cache:
    image: redis:7-alpine
    container_name: myapp-cache
    
    ports:
      - "6379:6379"
    
    volumes:
      - redis_data:/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf  # Custom конфигурация
    
    command: redis-server /usr/local/etc/redis/redis.conf
    
    networks:
      - app-network
    
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      timeout: 3s
      retries: 5
  
  # === MIGRATIONS (опционально) ===
  migrations:
    build: .
    container_name: myapp-migrations
    
    environment:
      DATABASE_URL: postgresql://dbuser:password@db:5432/myapp
    
    volumes:
      - .:/app
    
    working_dir: /app
    command: alembic upgrade head  # Или: python manage.py migrate
    
    depends_on:
      db:
        condition: service_healthy
    
    networks:
      - app-network

# === VOLUMES (именованные тома) ===
volumes:
  postgres_data:              # Данные БД
  redis_data:                 # Кэш Redis
  app_logs:                   # Логи приложения

# === NETWORKS (сеть для общения контейнеров) ===
networks:
  app-network:
    driver: bridge

Ключевые элементы конфигурации

1. Build vs Image

# Опция A: Собираем образ из Dockerfile
build:
  context: .
  dockerfile: Dockerfile

# Опция B: Используем готовый образ из реестра
image: postgres:15

# Опция C: Обе опции (сначала build, если не существует, то image)
build: .
image: myapp:latest

2. Environment переменные

# Вариант 1: Inline
environment:
  - DATABASE_URL=postgresql://localhost/db
  - DEBUG=true

# Вариант 2: Из .env файла
env_file: .env

# Вариант 3: Mix (env_file + inline переопределение)
env_file:
  - .env
environment:
  DEBUG: "true"  # Переопределяем значение из .env

3. Volumes (три типа)

volumes:
  # Тип 1: Bind mount (папка хоста -> контейнер)
  - .:/app                  # Для разработки
  
  # Тип 2: Named volume (управляемый Docker)
  - postgres_data:/var/lib/postgresql/data  # Для данных
  
  # Тип 3: Read-only
  - ./config:/etc/config:ro  # Только читаемое

4. Ports

ports:
  # Format: "host_port:container_port"
  - "8000:8000"              # HTTP
  - "8001:8001"              # HTTPS
  - "127.0.0.1:5432:5432"    # Только localhost (для БД)
  - "8080:8080/udp"          # UDP протокол

5. Depends On с health checks

depends_on:
  db:
    condition: service_healthy  # Ждём пока БД будет готова
  cache:
    condition: service_started   # Ждём просто старта

Это важно, потому что контейнер может запуститься, но приложение внутри ещё не готово к работе.

6. Health checks

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
  interval: 10s      # Проверяем каждые 10 секунд
  timeout: 5s        # Таймаут проверки
  retries: 3         # Сколько раз можно переиспробовать
  start_period: 30s  # Дать время на загрузку приложения

.env файл (для Docker Compose)

# .env
DATABASE_URL=postgresql://user:password@db:5432/myapp
REDIS_URL=redis://cache:6379/0
SECRET_KEY=your-secret-key-here
DEBUG=false
LOG_LEVEL=info

# БД
DB_PASSWORD=secure_password
POSTGRES_USER=dbuser

Команды для работы

# Запустить сервисы
docker compose up

# Запустить в фоне
docker compose up -d

# Перестроить образы
docker compose up --build

# Остановить сервисы
docker compose down

# Удалить данные (volumes)
docker compose down -v

# Посмотреть логи
docker compose logs app
docker compose logs -f app  # Follow (реал-тайм)

# Выполнить команду в контейнере
docker compose exec app python manage.py migrate

# Запустить тесты
docker compose run app pytest

# Интерактивный bash
docker compose exec app bash

Лучшие практики

DO:

  • Использовать named volumes для данных
  • Добавлять health checks
  • Указывать версию образов (не latest)
  • Использовать depends_on с условиями
  • Отделять dev и prod конфигурации
  • Документировать кастомные переменные
  • Исключать __pycache__, .git через .dockerignore

DON'T:

  • Хардкодить пароли (используй .env)
  • Использовать root пользователя в контейнере
  • Забывать про health checks
  • Маппировать все порты
  • Игнорировать лимиты памяти
  • Хранить логи в контейнере (используй volumes)

Пример для разработки vs Production

# docker-compose.yml (разработка)
version: '3.8'
services:
  app:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - .:/app  # Горячая перезагрузка
    command: python -m uvicorn main:app --reload

# docker-compose.prod.yml (production)
version: '3.8'
services:
  app:
    image: myapp:v1.2.3  # Конкретная версия
    ports:
      - "8000:8000"
    # БЕЗ volumes (только данные в named volumes)
    deploy:
      resources:
        limits:
          memory: 2G
    restart_policy:
      condition: on-failure
      max_attempts: 5

Запуск:

# Dev
docker compose up

# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up

Вывод

Хорошая Docker Compose конфигурация должна быть:

  • Полной — все необходимые сервисы и настройки
  • Безопасной — пароли в .env, not root
  • Надёжной — health checks, лимиты, перезапуски
  • Документированной — комментарии о нестандартных решениях
  • Воспроизводимой — один docker compose up и всё работает

Это инвестиция, которая сэкономит часы при onboarding и debug production проблем.

Что должно быть указано в конфигурации Docker Compose? | PrepBro