Ответ
Основная задача 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, логи и временные файлы.