Docker: cattivo consiglio

Docker: cattivo consiglio

Quando stavo imparando a guidare un'auto, alla primissima lezione l'istruttore è entrato all'incrocio in retromarcia e poi ha detto che non dovresti farlo, mai affatto. Mi sono ricordato di questa regola immediatamente e per il resto della mia vita.

Leggi "Cattivi consigli" di Grigorij Oster ai bambini e vedi con quanta facilità e naturalezza si rendono conto che non dovrebbero farlo.

Sono stati scritti molti articoli su come scrivere correttamente un Dockerfile. Ma non ho trovato istruzioni su come scrivere Dockerfile errati. Sto colmando questa lacuna. E forse nei progetti che ricevo supporto ci saranno meno dockerfile di questo tipo.

Tutti i personaggi, le situazioni e il Dockerfile sono fittizi. Se ti riconosci, scusa.

Creazione di un Dockerfile, inquietante e terribile

Peter (sviluppatore Java/rubby/php senior): Collega Vasily, hai già caricato un nuovo modulo su Docker?
Vasily (junior): No, non ho avuto tempo, non riesco a capirlo con questo Docker. Ci sono così tanti articoli a riguardo, è da capogiro.

Peter: Avevamo una scadenza un anno fa. Lascia che ti aiuti, lo scopriremo durante il processo. Dimmi cosa non funziona per te.

Vasily: Non posso scegliere un'immagine di base in modo che sia minimale, ma abbia tutto ciò di cui hai bisogno.
Peter: Prendi l'immagine di Ubuntu, ha tutto ciò di cui hai bisogno. E quante cose inutili torneranno utili in seguito. E non dimenticare di inserire il tag latest in modo che la versione sia sempre la più recente.

E la prima riga appare nel Dockerfile:

FROM ubuntu:latest

Peter: Qual è il passo successivo, cosa abbiamo usato per scrivere il nostro modulo?
Vasily: Allora, Ruby, c'è un server web e dovrebbero essere lanciati un paio di demoni di servizio.
Peter: Sì, di cosa abbiamo bisogno: ruby, bundler, nodejs, imagemagick e cos'altro... E allo stesso tempo, fare un aggiornamento per ottenere sicuramente nuovi pacchetti.
Vasily: E non creeremo un utente in modo da non essere root?
Peter: Fanculo, allora dovrai ancora scherzare con i diritti.
Vasily: Ho bisogno di tempo, circa 15 minuti, per mettere tutto insieme in un comando, ho letto che...
(Peter interrompe bruscamente il meticoloso e molto intelligente junior.)
Peter: Scrivi comandi separati, sarà più facile da leggere.

Il Dockerfile cresce:

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

Poi Igor Ivanovich, DevOps (ma più Ops che Dev), irrompe nell'ufficio gridando:

AI: Petya, i tuoi sviluppatori hanno rotto di nuovo il database del cibo, quando finirà tutto questo...

Dopo una piccola scaramuccia, Igor Ivanovich si calma e inizia a scoprire cosa ci fanno qui i suoi colleghi.

AI: Cosa stai facendo?
Vasily: Peter mi sta aiutando a creare un Dockerfile per un nuovo modulo.
AI: Fammi dare un'occhiata... Cosa hai scritto qui, pulisci il repository con un comando separato, questo è un livello aggiuntivo... Ma come installi le dipendenze se non hai copiato il Gemfile! E in generale, questo non va bene.
Peter: Per favore, fatti gli affari tuoi, troveremo una soluzione in qualche modo.

Igor Ivanovich sospira tristemente e parte per capire chi ha rotto il database.

Peter: Sì, ma aveva ragione riguardo al codice, dobbiamo inserirlo nell'immagine. E installiamo subito ssh e supervisor, altrimenti avviamo i demoni.

Vasily: Allora copierò prima Gemfile e Gemfile.lock, poi installerò tutto e poi copierò l'intero progetto. Se il Gemfile non cambia, il layer verrà preso dalla cache.
Peter: Perché siete tutti con questi strati, copiate tutto in una volta. Copia subito. La primissima riga.

Il Dockerfile ora assomiglia a questo:

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: Allora, e dopo? Hai configurazioni per il supervisore?
Vasily: No, no. Ma lo farò velocemente.
Peter: Allora lo farai. Disegniamo ora uno script init che avvierà tutto. Ok, quindi avvia ssh, con nohup, in modo che possiamo connetterci al contenitore e vedere cosa è andato storto. Quindi esegui Supervisor allo stesso modo. Bene, allora gestisci il passeggero.
D: Ma ho letto che dovrebbe esserci un processo, quindi Docker saprà che qualcosa è andato storto e potrà riavviare il contenitore.
P: Non ti tormentare con sciocchezze. E in generale, come? Come si esegue tutto questo in un unico processo? Lascia che Igor Ivanovich pensi alla stabilità, non per niente riceve uno stipendio. Il nostro compito è scrivere codice. E in generale, lascialo ringraziare per aver scritto il Dockefile per lui.

10 minuti e due video sui gatti più tardi.

D: Ho fatto tutto. Ho aggiunto più commenti.
P: Mostramelo!

Ultima versione di 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: Ottimo, mi piace. E i commenti sono in russo, comodi e leggibili, tutti funzionerebbero così. Ti ho insegnato tutto, il resto puoi farlo da solo. Andiamo a prendere un caffè...

Bene, ora abbiamo un Dockerfile assolutamente terribile, la cui vista farà venire voglia a Igor Ivanovich di licenziarsi e gli faranno male gli occhi per un'altra settimana. Il Dockerfile, ovviamente, potrebbe essere anche peggio, non c'è limite alla perfezione. Ma per cominciare, questo andrà bene.

Vorrei concludere con una citazione di Grigory Oster:

Se non sei ancora sicuro
Abbiamo scelto la strada della vita,
E non sai perché
Inizia il tuo viaggio lavorativo,
Rompi le lampadine nei corridoi -
La gente ti dirà "Grazie".
Aiuterai la gente
Risparmia elettricità.

Fonte: habr.com

Aggiungi un commento