Docker: шкідливі поради

Docker: шкідливі поради

Коли я вчився водити машину, на першому ж занятті інструктор виїхав на перехрестя заднім ходом, а потім сказав, що робити так не можна взагалі ніколи. Це правило я запам'ятав одразу і на все життя.

Читаєш дітям «Шкідливі поради» Григорія Остера, і бачиш, як легко та невимушено до них доходить, що так робити не можна.

Про те, як правильно писати Dockerfile, написано купу статей. Але мені не траплялося інструкцій, як писати неправильні Dockerfile. Відновлюю цю прогалину. І, можливо, в проектах, які я отримую на підтримку, таких докерфайлів поменшає.

Всі герої, ситуації та Dockerfile вигадані. Якщо ви впізнали себе, соррі.

Створюємо Dockerfile, зловісний та жахливий

Петро (Senior java/rubby/php developer): Колего Василю, ви вже залили в Docker новий модуль?
Василь (junior): Ні, не встиг, ніяк не розберуся із цим Docker. Стільки статей щодо нього, очі розбігаються.

Петро: У нас дедлайн рік тому вийшов. Давай допоможу, у процесі розберемося. Розповідай, що там у тебе не виходить.

Василь: Не можу вибрати базовий образ, щоби мінімальний, але було все, що потрібно.
Петро: Бери образ ubuntu, у ньому є все, що потрібно. А що багато зайвого, потім ще знадобиться. І не забудь поставити тег latest, щоб версія завжди була остання.

І в Dockerfile з'являється перший рядок:

FROM ubuntu:latest

Петро: Що там далі, що ми писали наш модуль?
Василь: Так ruby ​​жe, там веб-сервер і пара службових демонів має запускатися.
Петро: Ага, що нам треба: ruby, bundler, nodejs, imagemagick ну і що там ще… І заразом, зроби upgrade, щоб точно отримати нові пакети.
Василь: А користувача не створюватимемо, щоб не з-під 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 знатиме, що щось пішло не так, і зможе перезапустити контейнер.
П: Не забивай голову нісенітницею. І взагалі як? Як ти все це запустиш в одному процесі? Нехай про стабільність Ігор Іванович думає, чи не дарма він зарплату отримує. Наша справа код писати. І взагалі, нехай дякує, що ми написали за нього Dockefile.

Через 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

Додати коментар або відгук