Когда я учился водить машину, на первом же занятии инструктор выехал на перекресток задним ходом, а потом сказал, что делать так нельзя — вообще никогда. Это правило я запомнил сразу и на всю жизнь. Читаешь детям «Вредные советы» Григория Остера, и видишь, как легко и непринужденно до них доходит, что так делать нельзя. О том, как правильно писать Dockerfile, написана куча статей. Но мне не попадалось инструкций, как писать неправильные Dockerfile. Восполняю этот пробел. И, может быть, в проектах, которые я получаю на поддержку, таких докерфайлов станет меньше. Все герои, ситуации и Dockerfile вымышленные. Если вы узнали себя, сорри. Петр (Senior java/ruby/php developer): Коллега Василий, вы уже залили в Docker новый модуль?
Василий (junior): Нет, не успел, никак не разберусь с этим Docker. Столько статей по нему, глаза разбегаются. Петр: У нас дедлайн год назад вышел. Давай помогу, в процессе разберемся. Рассказывай, что там у тебя не получается. Василий: Не могу выбрать базовый образ, чтобы минимальный, но было все, что нужно.
Петр: Бери образ ubuntu, в нем есть все, что нужно. А что много лишнего, потом еще пригодится. И не забудь поставить тэг latest, чтобы версия всегда была самая последняя. И в Dockerfile появляется первая строка: Петр: Что там дальше, на чем мы писали наш модуль?
Василий: Так ruby жe, там веб сервер и пара служебных демонов должно запускаться.
Петр: Ага, что нам надо: ruby, bundler, nodejs, imagemagick ну и что там еще … И заодно, сделай upgrade, чтобы точно получить новые пакеты.
Василий: А пользователя не будем создавать, чтобы не из под root?
Петр: Да ну его, потом еще морочиться с правами.
Василий: Мне нужно время, минут 15, чтобы это все в одну команду слепить, я читал, что…
(Петр грубо прерывает дотошного и шибко умного джуна.)
Петр: Пиши отдельными командами, так и читать проще будет. Dockerfile растет: Тут в кабинет врывается Игорь Иванович, DevOps (но больше Ops, чем Dev), с криками: ИИ: Петя, твои разработчики опять разломали прод БД, когда же это закончится…. После небольшой перепалки Игорь Иванович остывает и начинает выяснять, чем коллеги тут занимаются. ИИ: Чем заняты?
Василий: Петр помогает мне составить Dockerfile для нового модуля.
ИИ: Дайте глянуть… Да что вы тут понаписали, вы же репозиторий чистите отдельной командой, это же дополнительный слой… Да как же вы ставите зависимости, если не скопировали Gemfile! И вообще, это никуда не годится.
Петр: Идите, пожалуйста, по своим делам, мы тут как-нибудь разберемся.  Игорь Иванович тоскливо вздыхает и уходит разбираться, кто таки сломал БД. Петр: Да, но про код-то он правильно сказал, надо его в имидж запихнуть. И давай сразу поставим ssh и supervisor, а то как мы демонов запускать будем. Василий: Я тогда сначала скопирую Gemfile и Gemfile.lock, потом все поставлю, и потом уже копирую весь проект. Если Gemfile не меняется, слой возьмется из кэша.
Петр: Что вы все с этими слоями, копируй сразу все. Сразу копируй. Первой же строкой. Dockerfile теперь выглядит так: Петр: Так, что дальше. У тебя есть конфиги для supervisor?
Василий: Нее, нету. Но я быстро сделаю.
Петр: Потом сделаешь. Давай сейчас набросаем init скрипт, который будет все запускать. Так-с, значит, запускаешь ssh, с nohup, чтобы мы могли подключиться к контейнеру и посмотреть, что пошло не так. Потом так же запускай supervisor. Ну и потом просто запустишь passenger.
В: Но я читал, что должен быть один процесс, так Docker будет знать, что что-то пошло не так, и сможет перезапустить контейнер.
П: Не забивай голову ерундой. И вообще, как? Как ты это все запустишь в одном процессе? Пусть о стабильности Игорь Иванович думает, не зря же он зарплату получает. Наше дело код писать. И вообще, пусть скажет спасибо, что мы написали за него Dockefile. Спустя 10 минут и два видеоролика про котиков. В: Я все сделал. Еще комментариев понадобавлял.
П: Показывай! Свежая версия Dockerfile: П: Отлично, мне нравится. И комментарии на русском, удобно и читаемо, все бы так работали. Я тебя всему научил, дальше сможешь сам. Пошли пить кофе... Ну, вот мы и получили идеально ужасный Dockerfile, от вида которого Игорь Иванович захочет уволиться и у него еще неделю будут болеть глаза. Dockerfile, конечно же, мог быть еще хуже, нет предела совершенству. Но для начала и так сойдет.  Закончить хотелось бы цитатой Григория Остера: Если вы еще не твердо
В жизни выбрали дорогу,
И не знаете, с чего бы
Трудовой свой путь начать,
Бейте лампочки в подъездах —
Люди скажут вам «Спасибо».
Вы поможете народу
Электричество беречь. UPD: В комментариях спрашивают, что не так в этих Dockerfile. На днях напишу отдельную статью с разбором ошибок. Ведущий инженер