Как создать Docker-образ для Python-приложения

Ответ

Для создания Docker-образа Python-приложения используется файл Dockerfile, который содержит пошаговые инструкции для сборки. Процесс включает выбор базового образа, установку зависимостей, копирование кода и определение команды запуска.

Базовый пример Dockerfile:

# 1. Выбор базового образа. Используем легковесный 'slim' вариант.
FROM python:3.9-slim

# 2. Установка рабочей директории внутри контейнера.
WORKDIR /app

# 3. Копирование файла зависимостей.
COPY requirements.txt .

# 4. Установка зависимостей. 
# --no-cache-dir уменьшает размер образа.
RUN pip install --no-cache-dir -r requirements.txt

# 5. Копирование исходного кода приложения.
COPY . .

# 6. Определение команды для запуска приложения при старте контейнера.
CMD ["python", "-u", "main.py"]

Ключевые практики для оптимизации:

  • Оптимизация кэширования слоев: Копирование requirements.txt и установка зависимостей выполняются до копирования исходного кода. Это позволяет Docker использовать кэш для слоя с зависимостями, если меняется только код, что значительно ускоряет пересборку.
  • Использование .dockerignore: Создайте файл .dockerignore, чтобы исключить из образа ненужные файлы и директории (например, .git, __pycache__, venv), уменьшая его размер и предотвращая утечку чувствительных данных.
  • Многоэтапные сборки (Multi-stage builds): Используются для сложных проектов, где для сборки требуются одни зависимости, а для запуска — другие. Это позволяет сохранить финальный образ минимальным, исключив из него сборочное окружение.

Ответ 18+ 🔞

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

Смотри, вот тебе священный текст, который называется Dockerfile. Это такая инструкция для долбоёба-компьютера, как собрать твоё приложение в аккуратную коробочку. Берёшь, пишешь, и потом можешь эту коробку запустить где угодно, хоть на сервере у китайцев, и оно, блядь, заработает. Волшебство, ёпта!

Вот, смотри, как это выглядит, если разложить по полочкам:

# 1. Берём основу. Брать последний питон — это как играть в русскую рулетку. Бери конкретную версию, да ещё и 'slim', чтоб не тащить в образ всё дерьмо мира.
FROM python:3.9-slim

# 2. Говорим: "Всё, пацаны, работаем тут". Создаём папку /app и делаем её нашей штаб-квартирой.
WORKDIR /app

# 3. Тащим в контейнер файлик requirements.txt. Только его, пока что. Это гениально, сейчас поймёшь почему.
COPY requirements.txt .

# 4. Ставим все зависимости, которые в requirements.txt. Флаг --no-cache-dir — это чтобы не тащить в образ кэш пипа, он нам нахуй не упёрся.
RUN pip install --no-cache-dir -r requirements.txt

# 5. А вот теперь, когда все библиотеки уже стоят, копируем ВЕСЬ остальной код. Весь свой гениальный, ебаный, кривой код.
COPY . .

# 6. И наконец, команда, которая запустится, когда контейнер оживёт. Как душа в тело вселится.
CMD ["python", "-u", "main.py"]

Теперь, сука, самое важное — почему мы скопировали requirements.txt отдельно, а потом уже весь код? А потому что Docker, блядь, умный! Он кэширует каждый шаг (слой). Если ты поменял свой код в main.py, но requirements.txt остался прежним, то Докер не будет заново ставить все эти дебильные библиотеки. Он возьмёт готовый слой из кэша! Экономия времени — овердохуища! А если бы ты скопировал всё разом, то любое изменение в любом файле заставляло бы переустанавливать зависимости. Пиздец и ужас.

Ещё одна хитрость, без которой ты — полупидор. Файлик .dockerignore. Создаёшь его рядом с Dockerfile и пишешь туда, что НЕ надо тащить в образ:

.git
__pycache__
venv
*.pyc
.env
README.md

Зачем? А затем, что иначе ты засунёшь в образ гигов 10 мусора, виртуальное окружение (которое, блядь, на другой ОС всё равно не работает), и, охуенно, свои секретные ключи из .env! Потом этот образ выложишь в публичный репозиторий, и все будут тебе благодарны за доступ к продовой базе. Чистый пиздец.

Ну и для совсем извращенцев есть многоэтапные сборки (Multi-stage builds). Это когда ты в одном Dockerfile делаешь два образа. Первый — толстый, уродливый, там компиляторы, сборщики и прочее дерьмо. В нём ты строишь своё приложение. А потом ты берёшь из этого урода только готовый бинарник или питоновский код и копируешь его во второй образ — маленький, чистый, голенький. А первый образ, сборочный, выкидываешь нахуй! Итоговый образ весит в разы меньше. Красота, блядь!

Вот и вся магия. Сначала кажется, что хуйня, а потом понимаешь, что это целая наука, чтобы не наступать на грабли. Удачи, только не забудь про .dockerignore, а то будет тебе привет от индийских хакеров!