Docker: zła rada

Docker: zła rada

Kiedy uczyłem się prowadzić samochód, już na pierwszej lekcji instruktor wjechał na skrzyżowanie tyłem, a potem powiedział, że nie należy tego robić – nigdy. Zapamiętałem tę zasadę od razu i na całe życie.

Czytasz dzieciom „Złe rady” Grigorija Ostera i widzisz, jak łatwo i naturalnie dociera do nich, że nie powinny tego robić.

Napisano wiele artykułów na temat prawidłowego pisania pliku Dockerfile. Ale nie natknąłem się na instrukcje dotyczące pisania nieprawidłowych plików Dockerfile. Wypełniam tę lukę. I może w projektach, które otrzymuję wsparcie, takich plików dockerfile będzie mniej.

Wszystkie postacie, sytuacje i plik Dockerfile są fikcyjne. Jeśli się rozpoznajesz, przepraszam.

Tworzenie pliku Dockerfile, złowieszcze i okropne

Peter (starszy programista Java/Rubby/php): Kolego Wasilij, czy wgrałeś już nowy moduł do Dockera?
Wasilij (junior): Nie, nie miałem czasu, nie mogę tego rozgryźć z tym Dockerem. Jest tyle artykułów na ten temat, że to przyprawia o zawrót głowy.

Peter: Termin mieliśmy rok temu. Pozwól, że ci pomogę. Rozwiążemy to w trakcie. Powiedz mi, co Ci nie pasuje.

Wasilij: Nie mogę wybrać podstawowego obrazu, aby był minimalny, ale miał wszystko, czego potrzebujesz.
Peter: Weź obraz Ubuntu, ma wszystko, czego potrzebujesz. A to, co jest dużo niepotrzebnych rzeczy, przyda się później. I nie zapomnij umieścić najnowszego tagu, aby wersja była zawsze najnowsza.

Pierwsza linia pojawia się w pliku Dockerfile:

FROM ubuntu:latest

Piotr: Co dalej, z czego korzystaliśmy przy pisaniu naszego modułu?
Wasilij: A więc Ruby, istnieje serwer WWW i należy uruchomić kilka demonów usług.
Peter: Tak, czego potrzebujemy: Ruby, packager, nodejs, imagemagick i co jeszcze... A jednocześnie wykonaj aktualizację, aby na pewno otrzymać nowe pakiety.
Wasilij: I nie utworzymy użytkownika, abyśmy nie byli zrootowani?
Peter: Pieprzyć to, w takim razie nadal będziesz musiał kombinować z prawami.
Wasilij: Potrzebuję czasu, około 15 minut, żeby to wszystko złożyć w jedno polecenie, czytałem to...
(Peter niegrzecznie przerywa skrupulatnemu i bardzo inteligentnemu juniorowi.)
Piotr: Napisz osobno, będzie łatwiej przeczytać.

Plik Dockerfile rośnie:

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/*

Wtedy Igor Iwanowicz, DevOps (ale bardziej Ops niż Dev), wpada do biura i krzyczy:

AI: Petya, twoi programiści znowu zepsuli bazę danych żywności, kiedy to się skończy…

Po małej potyczce Igor Iwanowicz otrząsa się i zaczyna dowiadywać się, co tu robią jego koledzy.

AI: Co robisz?
Wasilij: Peter pomaga mi stworzyć plik Dockerfile dla nowego modułu.
AI: Pozwól, że spojrzę... Co tu napisałeś, repozytorium czyścisz osobnym poleceniem, to jest dodatkowa warstwa... Ale jak zainstalować zależności, jeśli nie skopiowałeś Gemfile! I ogólnie to nie jest dobrze.
Peter: Proszę zająć się swoimi sprawami, jakoś to rozwiążemy.

Igor Iwanowicz wzdycha smutno i wychodzi, aby dowiedzieć się, kto złamał bazę danych.

Peter: Tak, ale miał rację co do kodu, musimy go wcisnąć w obraz. I od razu zainstalujmy ssh i nadzorcę, w przeciwnym razie uruchomimy demony.

Wasilij: Następnie skopiuję najpierw plik Gemfile i Gemfile.lock, następnie zainstaluję wszystko, a następnie skopiuję cały projekt. Jeśli plik Gemfile nie ulegnie zmianie, warstwa zostanie pobrana z pamięci podręcznej.
Peter: Po co ci wszyscy te warstwy, skopiuj wszystko na raz. Skopiuj od razu. Pierwsza linijka.

Plik Dockerfile wygląda teraz tak:

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/* 

Piotr: No i co dalej? Czy masz konfigurację dla nadzorcy?
Wasilij: Nie, nie. Ale zrobię to szybko.
Piotr: Więc to zrobisz. Narysujmy teraz skrypt inicjujący, który uruchomi wszystko. OK, więc uruchamiasz ssh za pomocą Nohup, abyśmy mogli połączyć się z kontenerem i zobaczyć, co poszło nie tak. Następnie uruchom nadzorcę w ten sam sposób. Cóż, w takim razie po prostu jedziesz jako pasażer.
P: Ale przeczytałem, że powinien istnieć jeden proces, aby Docker wiedział, że coś poszło nie tak i mógł zrestartować kontener.
P: Nie zawracaj sobie głowy bzdurami. I ogólnie jak? Jak uruchomić to wszystko w jednym procesie? Niech Igor Iwanowicz pomyśli o stabilności, nie bez powodu otrzymuje pensję. Naszym zadaniem jest pisanie kodu. I ogólnie niech podziękuje, że napisaliśmy dla niego Dockefile.

10 minut i dwa filmy o kotach później.

P: Zrobiłem wszystko. Dodałem więcej komentarzy.
P: Pokaż mi!

Najnowsza wersja 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”]

P: Świetnie, podoba mi się. A komentarze są po rosyjsku, wygodne i czytelne, każdy by tak działał. Nauczyłem cię wszystkiego, resztę możesz zrobić sam. Chodźmy napić się kawy...

Cóż, teraz mamy idealnie okropny plik Dockerfile, którego widok sprawi, że Igor Iwanowicz będzie chciał rzucić palenie, a oczy będą go boleć przez kolejny tydzień. Dockerfile oczywiście mógłby być jeszcze gorszy, nie ma ograniczeń co do doskonałości. Ale na początek to wystarczy.

Chciałbym zakończyć cytatem Grigorija Ostera:

Jeśli jeszcze nie jesteś pewien
Wybraliśmy ścieżkę życia,
I nie wiesz dlaczego
Rozpocznij swoją podróż zawodową,
Zniszcz żarówki w korytarzach -
Ludzie powiedzą Ci „dziękuję”.
Pomożesz ludziom
Oszczędzać prąd.

Źródło: www.habr.com

Dodaj komentarz