Ответ
Основная задача 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-папка со всей историей, логи, кэш и прочая манда с ушами. Образ раздует так, что сам от себя охуеешь. Создай файлик и перечисли там всё, что не должно попасть внутрь.
Вот так, коротко и без воды. Делай по этим правилам, и твои образы будут быстрыми, безопасными и маленькими. А не как у некоторых — пидарас шерстяной собрал, что бензина жрёт дофига и сломаться может от чиха.