Как написать Dockerfile

«Как написать Dockerfile» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основная задача Dockerfile — создать минимальный, безопасный и воспроизводимый образ. Вот пример для Python-приложения с лучшими практиками:

# 1. Используем конкретный тег для воспроизводимости и slim-версию для уменьшения размера
FROM python:3.9-slim AS builder

# 2. Устанавливаем системные зависимости, если нужны компилируемые пакеты (например, для psycopg2)
RUN apt-get update && apt-get install -y --no-install-recommends 
    gcc 
    libpq-dev 
    && rm -rf /var/lib/apt/lists/*

# 3. Создаем непривилегированного пользователя для безопасности
RUN useradd --create-home appuser
WORKDIR /home/appuser/app

# 4. Копируем и устанавливаем зависимости отдельным слоем для кэширования
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# 5. Финальный образ (мультистадийная сборка)
FROM python:3.9-slim
RUN useradd --no-create-home --shell /bin/false appuser
WORKDIR /app

# 6. Копируем только установленные пакеты из builder-стадии
COPY --from=builder /home/appuser/.local /home/appuser/.local
COPY --chown=appuser:appuser . .

# 7. Добавляем путь к pip-пакетам и переключаем пользователя
ENV PATH=/home/appuser/.local/bin:$PATH
USER appuser

# 8. Запускаем приложение
CMD ["python", "app.py"]

Ключевые принципы:

  • Многостадийность: Уменьшает итоговый размер образа, исключая инструменты сборки.
  • Слои: Часто меняющиеся команды (например, COPY . .) размещаются в конце, редко меняющиеся (установка зависимостей) — в начале для эффективного кэширования.
  • Безопасность: Запуск от непривилегированного пользователя (USER appuser) снижает риски.
  • .dockerignore: Обязательно используйте файл .dockerignore, чтобы не копировать в образ node_modules, .git, логи и временные файлы.