
Привет, я Дмитрий Желудков, архитектор по эксплуатации, и сегодня я покажу, как собрать приложение в 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)
Katasonov
24.07.2025 22:08запускалось одинаково везде (даже на машине тёти Зины);
Я уж было обрадовался и подумал расскажут как можно любое windows GUI приложение в докер запаковать и тете Зине отправить в виде исполняемого файла с автоматически разворачивающимся контейнером при старте.
А тут элементарная инструкция, которая выражается чатгпт за 10 секунд на запрос "как запустить хелло Ворд на питоне в докер" и реклама какого-то курса. Хабр уже не торт :(
InsaneLesha2
24.07.2025 22:08Причём здесь хабр? Эта статья ( под заголовком сразу написано) находится а разделе блога конторы, продающей онлайн курсы))))
Katasonov
24.07.2025 22:08на нем не должно быть такого низкокачественного шлака не зависимо от... Потому что так или иначе он попадает в новостные ленты телефонов где-то индексируясь, а мы тратим на это время.
trabl
На самом деле в файле requirements.txt необходимо указывать конкретные версии библиотек. Вы же не хотите получить не рабочее приложение в docker через неопределённое время? В самом app.py можно указать шибанг python и в CMD указать просто название скрипта, сделав его исполняемым, но здесь наверное ни к чему. Если подумать в сторону безопасности, то можно запускать приложение в контейнере не из под root.