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

Ответ

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

Ответ 18+ 🔞

Э, слушай, а вот это реально годный пример, ёпта. Смотри, как надо делать, чтобы потом не орать «ёперный театр, почему образ весит как танк и любой желающий может впендюрить в него вилкой».

Вот смотри, как умные люди делают:

# 1. Берём конкретную версию, а не latest, и 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. Сначала копируем только requirements.txt и ставим зависимости. Это для кэша, чтобы при каждом изменении кода не пересобирать всё с нуля.
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. Тащим установленные пакеты из первой стадии и уже потом весь наш код.
COPY --from=builder /home/appuser/.local /home/appuser/.local
COPY --chown=appuser:appuser . .

# 7. Прописываем путь и переключаемся на нашего непривилегированного юзера. Руту тут делать нехуй.
ENV PATH=/home/appuser/.local/bin:$PATH
USER appuser

# 8. И поехали
CMD ["python", "app.py"]

А теперь, бля, главные мысли, чтобы не быть распиздяем:

  • Многостадийность — это наш друг. Первый образ — это как строительная площадка, там грязь, инструменты. А финальный — это чистенькая квартира, куда мы занесли только мебель. Никакого лишнего хлама.
  • Слои — это всё. То, что меняется редко (типа установки зависимостей), ставим в начале. То, что меняется постоянно (наш код), — в самом конце. Иначе каждый раз при пуше новой строчки кода будешь ждать, пока pip install отработает. Доверия ебать ноль к такому процессу.
  • Безопасность — не просто слово. Запускать контейнер от рута — это как оставить ключи от квартиры в двери. USER appuser — наше всё.
  • .dockerignore — святое. Бля, чувак, если ты забудешь этот файл, то в образ попадёт всякая хуйня: node_modules, который весит тонну, .git-папка со всей историей, логи, кэш и прочая манда с ушами. Образ раздует так, что сам от себя охуеешь. Создай файлик и перечисли там всё, что не должно попасть внутрь.

Вот так, коротко и без воды. Делай по этим правилам, и твои образы будут быстрыми, безопасными и маленькими. А не как у некоторых — пидарас шерстяной собрал, что бензина жрёт дофига и сломаться может от чиха.