
Когато започвах да шофирам, на първия урок инструкторът изведнъж тръгна назад на кръстовището, а после каза, че така не може да се прави — никога. Това правило го запомних веднага и за цял живот.
Четеш на децата "Вредни съвети" на Григорий Остер и виждаш колко лесно и неусетно за тях става ясно, че така не трябва да се прави.
За това как да пишеш Dockerfile са написани куп статии. Но никъде не съм попадал на инструкции как да се пишат неправилни Dockerfile. Запълвам този пропуск. И, може би, в проектите, които получавам за поддръжка, такива докерфайлове ще станат по-малко.
Всички герои, ситуации и Dockerfile са измислени. Ако се разпознаете, съжалявам.
Създаваме Dockerfile, зловещ и ужасен
Петър (старши java/ruby/php разработчик): Колега Василий, ти вече ли качи новия модул в Docker?
Василий (младши): Не, не успях, никак не мога да разбера този Docker. Толкова статии по него, очите ми се замъгляват.
Петър: Нашият краен срок изтече миналата година. Хайде, ще помогна, в процеса ще разберем. Разказвай, какво не ти се получава.
Василий: Не мога да избера базовия образ, който да е минимален, но да има всичко необходимо.
Петър: Вземи образа ubuntu, в него има всичко, което ти трябва. А ако има много излишно, после пак ще ти е от полза. И не забравяй да сложиш таг latest, за да е версията винаги последна.
И в Dockerfile се появява първият ред:
FROM ubuntu:latestПетър: Какво следва, с какво писахме нашия модул?
Василий: А, така е ruby, там трябва да се стартира уеб сървър и няколко служебни демона.
Петър: Ясно, какво ни трябва: ruby, bundler, nodejs, imagemagick и какво ли още … И заедно, направи обновление, за да получиш новите пакети.
Василий: Няма ли да създадем потребител, за да не работим под root?
Петър: О, не, ще трябва да се занимаваме с правата после.
Василий: Нуждая се от време, минути 15, за да събера всичко в една команда, четох, че …
(Петър грубо прекъсва детайлния и прекалено умен младши.)
Петър: Пиши отделни команди, така ще е по-лесно за четене.
Dockerfile расте:
FROM ubuntu:latest
RUN apt-get update
RUN apt-get upgrade
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full
RUN gem install bundler
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
RUN bundle install --without development test --path vendor/bundle
RUN rm -rf /usr/local/bundle/cache/*.gem
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*В помещението втурва Игор Иванович, DevOps (но повече Ops, отколкото Dev), крещейки:
И.И.: Петя, твоите разработчици пак счупиха продукционната БД, кога ще свърши това…
След кратка спора, Игор Иванович се успокоява и започва да разбира какво точно правят колегите тук.
ИИ: С какво са заети?
Василий: Петър ми помага да съставя Dockerfile за новия модул.
ИИ: Дайте да погледна… Какво сте написали, вие чистите репозитория с отделна команда, това е допълнителен слой… Как така поставяте зависимости, ако не сте копирали Gemfile! И изобщо, това не върши работа.
Петър: Моля, идете по вашите работи, ние ще се справим тук.
Игор Иванович тъжно въздъхва и отива да разбере кой е счупил БД.
Петър: Да, но каза правилно за кода, трябва да го запишем в имиджа. И нека веднага поставим ssh и supervisor, защото как ще стартираме демоните.
Василий: Първо ще копирам Gemfile и Gemfile.lock, след това ще инсталирам всичко и накрая ще копирам целия проект. Ако Gemfile не се променя, слой ще се вземе от кеша.
Петър: Какво все с тези слоеве, копирай веднага всичко. Копирай веднага. С първия ред.
Dockerfile сега изглежда така:
FROM ubuntu:latest
COPY . /app
WORKDIR /app
RUN apt-get update
RUN apt-get upgrade
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor
RUN gem install bundler
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
RUN bundle install --without development test --path vendor/bundle
RUN rm -rf /usr/local/bundle/cache/*.gem
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* Петър: Така, какво следва. Имаш ли конфигурации за supervisor?
Василий: Не, нямам. Но бързо ще направя.
Петър: После ще го направиш. Нека сега да начертаем init скрипт, който ще стартира всичко. Значи, пускаш ssh с nohup, за да можем да се свържем с контейнера и да видим какво не е наред. После така също пускаш supervisor. И просто ще пуснеш passenger.
В: Но чух, че трябва да има един процес, така Docker ще знае, че нещо не е наред и ще може да рестартира контейнера.
П: Не се занимавай с глупости. И изобщо как? Как ще запуснеш всичко това в един процес? Нека Игор Иванович мисли за стабилността, не напразно получава заплата. Нашата работа е да пишем код. И да, нека да му кажем благодаря, че написахме Dockerfile вместо него.
След 10 минути и два видеоклипа с котки.
В: Всичко направих. Додадох и още коментари.
П: Покажи!
Свежа версия на Dockerfile:
FROM ubuntu:latest
# Копираме изходния код
COPY .\/\/app
WORKDIR /app
# Обновяваме списъка с пакети
RUN apt-get update
# Обновяваме пакетите
RUN apt-get upgrade
# Инсталираме нужните пакети
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor
# Инсталираме bundler
RUN gem install bundler
# Инсталираме nodejs, използван за сглобяване на статиката
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
# Инсталираме зависимостите
RUN bundle install --without development test --path vendor/bundle
# Чистим кешовете
RUN rm -rf /usr/local/bundle/cache/*.gem
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Стартираме скрипта при стартирането на контейнера, който ще стартира всичко останало.
CMD ["/app/init.sh"]П: Отлично, харесва ми. И коментарите на български, удобно и четливо, всеки би работил така. Научих те на всичко, занапред можеш сам. Хайде да отидем на кафе…
Е, ето ни с идеално ужасния Dockerfile, от който Игор Иванович ще поиска да се уволни, а очите му ще болят още седмица. Dockerfile, разбира се, можеше да бъде и по-лош, няма предел на съвършенството. Но за начало и така е добре.
Искам да завърша с цитат на Григорий Остър:
Ако в живота ви все още не сте решили
Коя е пътят ви,
И не знаете от къде да
Започнете трудовия си път,
Прибивайте крушки в стълбищата —
Хората ще ви кажат "Благодаря".
Ще помогнете на народа
Да спестява електричество.
Източник: habr.com
