Docker: schlechter Rat

Docker: schlechter Rat

Als ich Autofahren lernte, fuhr der Fahrlehrer gleich in der ersten Unterrichtsstunde rückwärts in die Kreuzung und sagte dann, dass man das nicht tun solle – auf keinen Fall. Ich erinnerte mich sofort und für den Rest meines Lebens an diese Regel.

Sie lesen Kindern „Bad Advice“ von Grigory Oster vor und sehen, wie leicht und natürlich ihnen klar wird, dass sie dies nicht tun sollten.

Es wurden viele Artikel darüber geschrieben, wie man eine Docker-Datei richtig schreibt. Aber ich habe keine Anleitung gefunden, wie man falsche Docker-Dateien schreibt. Ich fülle diese Lücke. Und vielleicht wird es in den Projekten, die ich unterstützt bekomme, weniger solcher Dockerfiles geben.

Alle Charaktere, Situationen und Dockerfiles sind fiktiv. Wenn Sie sich selbst wiedererkennen, tut mir leid.

Eine Docker-Datei erstellen, bedrohlich und schrecklich

Peter (leitender Java/Rubby/PHP-Entwickler): Kollege Vasily, haben Sie bereits ein neues Modul auf Docker hochgeladen?
Vasily (Junior): Nein, ich hatte keine Zeit, ich kann es mit diesem Docker nicht herausfinden. Es gibt so viele Artikel darüber, es ist schwindelerregend.

Peter: Wir hatten vor einem Jahr eine Frist. Lassen Sie mich Ihnen helfen, wir werden es dabei herausfinden. Sagen Sie mir, was bei Ihnen nicht funktioniert.

Vasily: Ich kann kein einfaches Bild wählen, das minimal ist, aber alles hat, was Sie brauchen.
Peter: Nehmen Sie das Ubuntu-Image, es hat alles, was Sie brauchen. Und was viele unnötige Dinge sind, wird sich später als nützlich erweisen. Und vergessen Sie nicht, das neueste Tag einzufügen, damit die Version immer die neueste ist.

Und die erste Zeile erscheint im Dockerfile:

FROM ubuntu:latest

Peter: Wie geht es weiter? Womit haben wir unser Modul geschrieben?
Vasily: Ruby, es gibt einen Webserver und ein paar Service-Daemons sollten gestartet werden.
Peter: Ja, was brauchen wir: Ruby, Bundler, NodeJS, Imagemagick und was sonst noch ... Und gleichzeitig ein Upgrade durchführen, um definitiv neue Pakete zu bekommen.
Vasily: Und wir werden keinen Benutzer erstellen, damit wir nicht unter Root stehen?
Peter: Scheiß drauf, dann musst du immer noch mit den Rechten herumalbern.
Vasily: Ich brauche Zeit, etwa 15 Minuten, um alles in einem Befehl zusammenzufassen, das habe ich gelesen...
(Peter unterbricht den akribischen und sehr klugen Junior grob.)
Peter: Schreiben Sie separate Befehle, das ist leichter zu lesen.

Dockerfile wächst:

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

Dann stürmt Igor Ivanovich, DevOps (aber mehr Ops als Dev), ins Büro und schreit:

AI: Petya, deine Entwickler haben die Lebensmitteldatenbank wieder kaputt gemacht, wann wird das enden ...

Nach einem kleinen Gefecht beruhigt sich Igor Iwanowitsch und beginnt herauszufinden, was seine Kollegen hier machen.

AI: Was machst du?
Vasily: Peter hilft mir, eine Docker-Datei für ein neues Modul zu erstellen.
AI: Lass mich einen Blick darauf werfen ... Was hast du hier geschrieben, du bereinigst das Repository mit einem separaten Befehl, das ist eine zusätzliche Ebene ... Aber wie installiert man Abhängigkeiten, wenn man die Gemfile nicht kopiert hat! Und im Allgemeinen ist das nicht gut.
Peter: Gehen Sie bitte Ihrem Geschäft nach, wir werden das schon irgendwie hinbekommen.

Igor Iwanowitsch seufzt traurig und geht, um herauszufinden, wer die Datenbank gehackt hat.

Peter: Ja, aber er hatte Recht mit dem Code, wir müssen ihn in das Bild einfügen. Und lasst uns sofort SSH und Supervisor installieren, sonst starten wir die Daemons.

Vasily: Dann kopiere ich zuerst Gemfile und Gemfile.lock, dann installiere ich alles und dann kopiere ich das gesamte Projekt. Wenn sich die Gemfile nicht ändert, wird die Ebene aus dem Cache entnommen.
Peter: Warum habt ihr alle diese Ebenen, kopiert alles auf einmal? Gleich kopieren. Die allererste Zeile.

Das Dockerfile sieht nun so aus:

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

Peter: Also, was kommt als nächstes? Haben Sie Konfigurationen für den Supervisor?
Wassili: Nein, nein. Aber ich mache es schnell.
Peter: Dann wirst du es tun. Lassen Sie uns nun ein Init-Skript skizzieren, das alles startet. Okay, Sie starten also SSH mit Nohup, damit wir uns mit dem Container verbinden und sehen können, was schief gelaufen ist. Führen Sie dann Supervisor auf die gleiche Weise aus. Na ja, dann fährst du einfach als Beifahrer.
F: Aber ich habe gelesen, dass es einen Prozess geben sollte, damit Docker weiß, dass etwas schief gelaufen ist, und den Container neu starten kann.
P: Mach dir nicht den Kopf mit Unsinn. Und im Allgemeinen, wie? Wie führt man das alles in einem Prozess aus? Lassen Sie Igor Iwanowitsch über Stabilität nachdenken, er erhält nicht umsonst ein Gehalt. Unsere Aufgabe ist es, Code zu schreiben. Und im Allgemeinen möchte er sich dafür bedanken, dass wir das Dockefile für ihn geschrieben haben.

10 Minuten und zwei Videos über Katzen später.

F: Ich habe alles getan. Ich habe weitere Kommentare hinzugefügt.
P: Zeig es mir!

Neueste Version von 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: Großartig, es gefällt mir. Und die Kommentare sind auf Russisch, praktisch und lesbar, jeder würde so arbeiten. Ich habe dir alles beigebracht, den Rest kannst du selbst erledigen. Lass uns einen Kaffee trinken gehen...

Nun haben wir eine völlig schreckliche Docker-Datei, deren Anblick Igor Iwanowitsch am liebsten aufgeben lassen würde und dessen Augen noch eine Woche lang schmerzen würden. Das Dockerfile könnte natürlich noch schlimmer sein, der Perfektion sind keine Grenzen gesetzt. Aber für den Anfang reicht das.

Ich möchte mit einem Zitat von Grigory Oster schließen:

Falls Sie sich noch nicht sicher sind
Wir haben den Weg im Leben gewählt,
Und Sie wissen nicht warum
Beginnen Sie Ihre Arbeitsreise,
Zerbrich die Glühbirnen in den Fluren –
Die Leute werden Ihnen „Danke“ sagen.
Du wirst den Menschen helfen
Spare Strom.

Source: habr.com

Kommentar hinzufügen