Привет, я Дмитрий Желудков, архитектор по эксплуатации, и сегодня я покажу, как собрать приложение в docker на вот этих вот 4 левых пальцах (а как же иначе, у нас же серьёзное исследование).

На незаданный вопрос я смело отвечу, что иногда требуется взять своё простое, но гордое приложение, и запустить его внутри контейнера, чтобы:

  • запускалось одинаково везде (даже на машине тёти Зины);

  • можно было задеплоить хоть в облако, хоть на ведро;

  • не думать про зависимости, версии, среды и вот это всё.

Как вы могли заметить, мы подошли к одному из постулатов эксплуатации: «В первую очередь, контейнер — это артефакт поставки приложения, а уже потом изоляция», и сделали важный шаг к большим оркестраторам k8s. 

Поехали к делу.

Простой пример: у нас есть приложение на Python, которое мы запускаем как python app.py. Ничего экзотического. Берём Python как самый популярный язык программирования в мире по версии TIOBE на июль 2025 года. На этом серьёзность исследования заканчиваем и дальше можно не ждать авторитетных источников).

Шаг 1. Готовим проект

Вот структура проекта:

myapp/

├── app.py

├── requirements.txt

app.py может быть хоть «Hello, world!», или же веб-приложение, не суть. Главное — он запускается и работает. Если же не запускается и не работает, то, боюсь, ваше приложение недостаточно гордое и придётся его доработать.

В requirements.txt перечислены зависимости, например:

flask

requests

В общем, полноценный проект, с большой буквы П.

Шаг 2. Пишем Dockerfile

Теперь создаём файл Dockerfile в корне проекта:

FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "app.py"]

Что тут происходит:

  • берём официальный образ Python, но облегчённый (slim);

  • переходим в директорию /app внутри контейнера;

  • копируем зависимости и ставим их через pip;

  • копируем весь проект внутрь контейнера;

  • запускаем app.py, когда контейнер стартует.

Dockerfile — это такой файл‑рецепт. Прям как инструкция к сборке мебели из ИКЕА, только для приложения. Ты пишешь в нём, из чего собирать образ (например, взять Ubuntu, поставить туда Python, или сразу взять Python, поставить зависимости), что скопировать внутрь, какие команды выполнить и как запускать это всё добро.

От этого куча плюсов: и версионирование вариантов сборок, и автоматизация сборки и доставки на стенды (вот это наше любимое CI/CD), и не надо объяснять новичку, как собирать проект «делай docker build».

Мы, собственно, уже написали файл-инструкцию о том, как упаковать наше гордое приложение в контейнер (включая зависимости), и как его запускать.

За скобками остаются такие вещи, как FROM scratch, почему python, а не alpine, и почему указана версия, а не latest, да и что такое latest, но, думаю, имея пытливый ум, вы найдёте ответы на эти вопросы.

Шаг 3. Собираем образ

В терминале, находясь в директории с Dockerfile, выполняем:

docker build -t myapp .

Это соберёт образ с тегом myapp. Docker пройдётся по Dockerfile и на каждый шаг сделает слой.

Так, стойте, какие слои, мы что, готовим пирог?

Да, слои в Docker — это как слоёный пирог, только вместо теста и начинки у нас команды из Dockerfile.

Каждая инструкция (FROM, COPY, RUN, CMD) — это один слой. И Docker собирает твой образ слой за слоем. Как только ты что-то написал в Dockerfile, он создаёт новый слой на основе предыдущего.

Зачем это всё?

Docker кеширует слои. Если ты не менял код, а просто перезапускаешь сборку, он не будет заново ставить Python или зависимости — он возьмёт готовые слои из кэша. Быстрее, дешевле, удобнее.

Ну и да: образы легче обновлять. Поменял только одну строчку? Пересобрался только один слой, остальное осталось как есть. Конечно, если у вас код подъезжает последними слоями, а не в первую очередь.

Так что слои — это и про оптимизацию, и про повторное использование, и вообще про порядок в контейнерной жизни.

Тут ещё можем рассказать о другие инструменты сборки, но это уже не про пальцы.

Шаг 4. Запускаем контейнер

Теперь можно запустить наше приложение в контейнере:

docker run --rm myapp

Если всё ок, увидим вывод от app.py. Можно порт пробросить, если приложение вебовое:

docker run -p 8000:8000 myapp

Опять же, под капотом и за кулисами есть всякое интересное: cgroup, namespace — но мы же сегодня про «4 простых шага для чайников».

Можно ещё ключ -d добавить, чтобы он в фон провалился. Или в compose обернуть, если у вас несколько сервисов и ещё база данных, и прочее сетевое взаимодействие. Ну или про структуру хранения файлов в Git-репозитории рассказать, и про CI, и много-много чего другого.

Но базово, вот так просто и без фанатизма, мы запихнули приложение в контейнер. 

Теперь можно в бой? На самом деле нет, ибо нюансов много, да и глубина кроличьей норы поражает. Но именно эта задумана как отправная точка в мир контейнеров для самых маленьких, с которой можно начинать знакомство.

Главное — не бойтесь Dockerfile. Он страшен только снаружи. А внутри — просто шаги, как в рецепте. 


Больше интересного и полезного про работу в Docker — на курсе Слёрма «Docker для админов и разработчиков». Если вы хотите освоить Docker с нуля и уверенно разворачивать, управлять и масштабировать приложения в реальных условиях, вам сюда.

Приятного контейнеринга!

Комментарии (4)


  1. trabl
    24.07.2025 22:08

    На самом деле в файле requirements.txt необходимо указывать конкретные версии библиотек. Вы же не хотите получить не рабочее приложение в docker через неопределённое время? В самом app.py можно указать шибанг python и в CMD указать просто название скрипта, сделав его исполняемым, но здесь наверное ни к чему. Если подумать в сторону безопасности, то можно запускать приложение в контейнере не из под root.


  1. Katasonov
    24.07.2025 22:08

    запускалось одинаково везде (даже на машине тёти Зины);

    Я уж было обрадовался и подумал расскажут как можно любое windows GUI приложение в докер запаковать и тете Зине отправить в виде исполняемого файла с автоматически разворачивающимся контейнером при старте.

    А тут элементарная инструкция, которая выражается чатгпт за 10 секунд на запрос "как запустить хелло Ворд на питоне в докер" и реклама какого-то курса. Хабр уже не торт :(


    1. InsaneLesha2
      24.07.2025 22:08

      Причём здесь хабр? Эта статья ( под заголовком сразу написано) находится а разделе блога конторы, продающей онлайн курсы))))


      1. Katasonov
        24.07.2025 22:08

        на нем не должно быть такого низкокачественного шлака не зависимо от... Потому что так или иначе он попадает в новостные ленты телефонов где-то индексируясь, а мы тратим на это время.