> Как сконфигурировать Docker и Docker Compose для Django приложения (Python)
Уровень: senior · Роль: backend · Язык: Python · Категория: Технические вопросы
Компании: Стилсофт
Стек: Python, Docker
> Пример ответа
Короткий ответ
Для Django-приложения нужен многоступенчатый Dockerfile: базовый образ для зависимостей, слой для сборки статики и финальный runtime-образ. Docker Compose описывает сервисы web, db (PostgreSQL) и, при необходимости, redis, nginx. Ключевые моменты: использование .dockerignore, отдельный requirements-файл для production, healthcheck для БД, volume для кода и статики, а также передача настроек через environment variables, а не через settings.py.
Подробное объяснение
Конфигурация Docker для Django сводится к двум уровням: образ и оркестрация. Образ должен быть минимальным, безопасным и воспроизводимым. Для этого используется multi-stage build: на первом этапе ставятся все зависимости, включая build-инструменты, на втором - только runtime-пакеты. Это уменьшает размер образа и поверхность атаки.
Docker Compose решает задачу локальной разработки и production-деплоя. В development режиме код монтируется volume'ом, чтобы изменения применялись без пересборки. В production код копируется в образ, а volume используется только для статики и медиа. Отдельный сервис для БД обязателен, так как Django не должен работать с БД внутри контейнера приложения.
Важный trade-off: использовать python:3.12-slim как базовый образ - он меньше, но требует установки системных библиотек для psycopg2. Альтернатива - python:3.12-alpine, но он может вызвать проблемы с компиляцией некоторых пакетов. Для senior-уровня важно уметь обосновать выбор.
На практике
Начинаем с .dockerignore - исключаем .git, __pycache__, venv, staticfiles, media. Затем Dockerfile: сначала pip install --no-cache-dir -r requirements.txt, потом копируем код. Для production добавляем gunicorn как entrypoint. В Compose указываем depends_on с condition: service_healthy для БД, чтобы Django не стартовал раньше PostgreSQL.
Для миграций используем отдельную команду docker compose run --rm web python manage.py migrate, а не выполняем их в entrypoint - это позволяет контролировать порядок при деплое. Статику собираем через collectstatic в volume, который шарится с nginx.
Пример кода
# Dockerfile FROM python:3.12-slim AS builder ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends gcc libpq-dev && rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt FROM python:3.12-slim ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 WORKDIR /app RUN apt-get update && apt-get install -y --no-install-recommends libpq && rm -rf /var/lib/apt/lists/* COPY --from=builder /wheels /wheels RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels COPY . . EXPOSE 8000 CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"]
YAML# docker-compose.ymlversion: "3.9"services:db:image: postgres:16-alpineenvironment:POSTGRES_DB: ${DB_NAME}POSTGRES_USER: ${DB_USER}POSTGRES_PASSWORD: ${DB_PASSWORD}volumes:- postgres_data:/var/lib/postgresql/datahealthcheck:test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]interval: 5stimeout: 5sretries: 5web:build: .command: gunicorn config.wsgi:application --bind 0.0.0.0:8000volumes:- static_volume:/app/staticfiles- media_volume:/app/mediaenv_file:- .envdepends_on:db:condition: service_healthyports:- "8000:8000"nginx:image: nginx:1.25-alpinevolumes:- ./nginx.conf:/etc/nginx/conf.d/default.conf- static_volume:/static- media_volume:/mediaports:- "80:80"depends_on:- webvolumes:postgres_data:static_volume:media_volume:
Как отвечать на собеседовании
Начни с целей: воспроизводимость, изоляция, простота деплоя. Затем опиши структуру образа и почему multi-stage. Обязательно упомяни healthcheck для БД и порядок запуска. Покажи понимание разницы между dev и prod конфигурациями - это ключевой сигнал для senior. Расскажи про обработку статики через nginx и почему не стоит отдавать её через Django в production. Если спросят про безопасность - скажи про запуск от non-root пользователя и --no-cache-dir.
Что проверяет интервьюер
Проверяется понимание жизненного цикла контейнера, умение проектировать инфраструктуру, а не просто писать Dockerfile. Важно, чтобы кандидат объяснил, зачем нужен каждый слой, как решаются проблемы с зависимостями и как обеспечить отказоустойчивость. Также оценивается знание best practices: .dockerignore, healthcheck, volumes, environment variables. Senior должен уметь аргументировать выбор базового образа и стратегию обновления зависимостей.
Типичные ошибки
- Запуск миграций в entrypoint - это приводит к гонкам при масштабировании.
- Использование
latestтегов для базовых образов - невоспроизводимо. - Хранение секретов в Dockerfile или Compose без env_file.
- Отсутствие
.dockerignore- образ раздувается. - Монтирование всего кода volume'ом в production - теряется изоляция.
- Запуск Django dev-server вместо gunicorn в production.
- Неправильная обработка статики: попытка отдавать её через Django или отсутствие volume для nginx.
> Похожие задачи по Python
Был ли опыт работы с MongoDB или аналогичными документно-ориентированными базами данных
Какие инструменты DRF и Django использовать для реализации бизнес-логики сохранения заказа?
Как конкретизировать промежуточную таблицу many-to-many в Django для добавления дополнительных полей
Какие варианты реализации взаимодействия фронтенда и бэкенда для долгих задач с отображением прогресса
> Похожие задачи по backend
Был ли опыт работы с MongoDB или аналогичными документно-ориентированными базами данных
Какие инструменты DRF и Django использовать для реализации бизнес-логики сохранения заказа?
Как конкретизировать промежуточную таблицу many-to-many в Django для добавления дополнительных полей
Какие варианты реализации взаимодействия фронтенда и бэкенда для долгих задач с отображением прогресса
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью