
Quand j'ai appris à conduire une voiture, dans la toute première leçon, l'instructeur est allé à l'intersection en sens inverse, puis a dit que vous ne devriez pas le faire - jamais du tout. Cette règle, je me suis souvenue immédiatement et pour la vie.
Vous lisez les «mauvais conseils» aux enfants de Grigory Oster, et vous voyez à quel point il leur est facile et naturel que cela ne puisse pas être fait.
De nombreux articles ont été écrits sur la façon d'écrire correctement Dockerfile. Mais je n'ai pas rencontré d'instructions sur la façon d'écrire le mauvais Dockerfile. Je comble cette lacune. Et peut-être que dans les projets que j'obtiens pour le soutien, il y aura moins de tels fichiers docker.
Tous les héros, situations et dockerfile sont fictifs. Si vous vous reconnaissez, désolé.
Créer un Dockerfile, Ominous et Terrible
Peter (développeur senior java / ruby / php): Collègue Vasily, avez-vous déjà téléchargé un nouveau module sur Docker?
Basil (junior): Non, je ne l'ai pas fait, je ne peux pas le comprendre avec ce Docker. Autant d'articles à ce sujet, mes yeux s'écarquillent.
Peter: Nous avons eu un délai il y a un an. Aidez-nous, nous allons le découvrir dans le processus. Dites-moi ce que vous ne pouvez pas faire là-bas.
Basil: Je ne peux pas choisir l'image de base pour qu'elle soit minimale, mais il y avait tout ce qui était nécessaire.
Peter: Prenez l'image d'ubuntu, il a tout ce dont vous avez besoin. Et quel excès, alors ce sera utile. Et n'oubliez pas de mettre la dernière balise pour que la version soit toujours la plus récente.
Et dans le Dockerfile, la première ligne apparaît:
FROM ubuntu:latest
Peter: Quelle est la prochaine étape, sur quoi avons-nous écrit notre module?
Basil: Alors rubis, un serveur Web et quelques démons de service devraient démarrer.
Peter: Oui, de quoi avons-nous besoin: ruby, bundler, nodejs, imagemagick alors quoi d'autre ... Et en même temps, mettez à niveau pour obtenir de nouveaux packages à coup sûr.
Basil: Et nous ne créerons pas l'utilisateur, donc pas à partir de la racine?
Peter: Oh, bien lui, alors continuez de jouer avec les droits.
Vasily: J'ai besoin de temps, environ 15 minutes, pour tout faire en une seule équipe, j'ai lu ça ...
(Peter interrompt brutalement le mois de juin méticuleux et très intelligent.)
Peter: Écrivez dans des équipes distinctes et ce sera plus facile à lire.
Dockerfile se développe:
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/*
Puis Igor Ivanovich a fait irruption dans le bureau, DevOps (mais plus d'Ops que de Dev), en criant:
AI: Petya, vos développeurs ont à nouveau cassé la base de données de prod, quand cela se termine-t-il ...
Après une petite escarmouche, Igor Ivanovich se refroidit et commence à découvrir ce que font ses collègues ici.
AI: Qu'est-ce que tu fais?
Basil: Peter m'aide à compiler un Dockerfile pour un nouveau module.
II: Jetons un coup d'œil ... Qu'est-ce que vous écrivez ici, vous nettoyez le référentiel avec une commande distincte, c'est une couche supplémentaire ... Mais comment mettre les dépendances si vous n'avez pas copié le Gemfile! Et de toute façon, ce n'est pas bon.
Peter: Je vous en prie, vaquer à vos occupations, nous trouverons une solution.
Igor Ivanovich soupire tristement et part découvrir qui a cassé la base de données.
Peter: Oui, mais à propos du code, il a dit la bonne chose, vous devez le bourrer dans l'image. Et mettons ssh et superviseur tout de suite, sinon nous allons démarrer les démons.
Vasily: Ensuite, je copie d'abord Gemfile et Gemfile.lock, puis je mets tout dedans, puis je copie tout le projet. Si le Gemfile ne change pas, la couche sera prise dans le cache.
Peter: Que faites-vous tous avec ces couches, copiez tout à la fois. Copiez tout de suite. La première ligne.
Dockerfile ressemble maintenant à ceci:
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: Alors quelle est la prochaine. Avez-vous des configurations pour le superviseur?
Basil: Non, non. Mais je vais le faire rapidement.
Peter: Alors fais-le. Esquissons maintenant le script init qui exécutera tout. Donc, avec cela, vous démarrez ssh avec nohup afin que nous puissions nous connecter au conteneur et voir ce qui s'est mal passé. Ensuite, lancez également le superviseur. Eh bien, courez juste passager.
Q: Mais j'ai lu qu'il devrait y avoir un processus, donc Docker saura que quelque chose s'est mal passé et peut redémarrer le conteneur.
P: Ne vous embêtez pas avec votre tête. Et en général, comment? Comment exécutez-vous tout cela en un seul processus? Laissez Igor Ivanovich penser à la stabilité, ce n'est pas pour rien qu'il reçoit un salaire. Notre métier est d'écrire du code. Et de toute façon, laissez-le dire merci d'avoir écrit le Dockefile pour lui.
Après 10 minutes et deux vidéos sur les chats.
Q: J'ai tout fait. J'ai également ajouté des commentaires.
P: Montre!
Nouvelle version de 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: Super, j'aime ça. Et les commentaires en russe sont pratiques et lisibles, tout le monde travaillerait comme ça. Je vous ai tout appris, alors vous pouvez le faire vous-même. Allons boire un café ...
Eh bien, nous avons ici un Dockerfile absolument terrible, à la vue duquel Igor Ivanovich veut arrêter et ses yeux lui feront mal pendant une autre semaine. Dockerfile, bien sûr, pourrait être encore pire, il n'y a pas de limite à la perfection. Mais pour commencer, ça suffira.
Je voudrais terminer avec une citation de Gregory Oster:
Si vous n'êtes pas encore ferme
Ils ont choisi la route
Et tu ne sais pas pourquoi
Travaillez votre chemin pour commencer,
Battez les lumières dans les porches -
Les gens vous diront merci.
Vous aiderez les gens
Protégez l'électricité.
UPD : Dans les commentaires, ils demandent ce qui ne va pas avec ces Dockerfiles. L'autre jour, j'écrirai un article séparé avec une analyse des erreurs.