Docker: consigli dannosi

Docker: consigli dannosi

Quando ho imparato a guidare, al primo incontro l'istruttore è uscito con la retro al semaforo e poi ha detto che non si può fare così, mai. Questa regola l'ho subito memorizzata per tutta la vita.

Leggi ai bambini "Consigli dannosi" di Grigorij Oster e vedi quanto facilmente e naturalmente capiscono che non si può fare così.

Ci sono molti articoli su come scrivere un Dockerfile correttamente. Ma non ho trovato istruzioni su come scrivere un Dockerfile sbagliato. Colmo questa lacuna. E magari, nei progetti che ricevo in supporto, ci saranno meno di questi Dockerfile.

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

Creiamo un Dockerfile, sinistro e spaventoso

Pietro (Senior java/ruby/php developer): Collega Vasilij, hai già caricato il nuovo modulo in Docker?
Vasilij (junior): No, non ce l'ho fatta, non riesco a capire bene Docker. Ci sono così tanti articoli che mi confondono.

Pietro: Il nostro deadline è scaduto un anno fa. Dai, ti aiuto, sistemiamo nel processo. Dimmi cosa non riesci a fare.

Vasilij: Non riesco a scegliere l'immagine di base, vorrei che fosse minima, ma con tutto il necessario.
Pietro: Prendi l'immagine di ubuntu, contiene tutto. Anche se c'è molto di superfluo, potrebbe tornarti utile in seguito. E non dimenticare di mettere il tag latest, per avere sempre l'ultima versione.

E nel Dockerfile appare la prima riga:

FROM ubuntu:latest

Pietro: Cosa c'è dopo, su cosa abbiamo scritto il nostro modulo?
Vasilij: Beh, su ruby, devono avviarsi un server web e un paio di demoni di servizio.
Pietro: Ah, quindi abbiamo bisogno di: ruby, bundler, nodejs, imagemagick e cosa altro ... E per una volta, fai un upgrade, così ottieni sicuramente i pacchetti nuovi.
Vasilij: Non creiamo un utente per non operare come root?
Pietro: Ma dai, poi ci si deve preoccupare dei permessi.
Vasilij: Ho bisogno di tempo, circa 15 minuti, per mettere tutto in un unico comando, ho letto che...
(Pietro interrompe bruscamente il juniore pedante e saputello.)
Pietro: Scrivi in comandi separati, sarà anche 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/*

In quel momento irrompe in ufficio Igor Ivanovich, DevOps (ma più Ops che Dev), urlando:

II: Petya, i tuoi sviluppatori hanno di nuovo distrutto il DB di produzione, quando finirà ...

Dopo una breve discussione, Igor Ivanovich si calma e inizia a chiedere cosa stiano facendo i suoi colleghi.

AI: A cosa siete occupati?
Vasiliy: Pietro mi sta aiutando a creare un Dockerfile per il nuovo modulo.
AI: Fammi vedere... Ma cosa avete scritto qui, pulite il repository con un comando separato, questo è uno strato aggiuntivo... E come installate le dipendenze se non avete copiato il Gemfile? E comunque, questo non va bene.
Pietro: Andate a fare i vostri affari, noi ci sistemiamo qui.

Igor Ivanovich sospira tristemente e va a scoprire chi ha rotto il database.

Pietro: Sì, ma ha ragione riguardo al codice, dobbiamo metterlo nell'immagine. E mettiamo subito ssh e supervisor, altrimenti come avviamo i demoni?

Vasiliy: Allora prima copierò il Gemfile e il Gemfile.lock, poi installerò tutto, e poi copierò il progetto intero. Se il Gemfile non cambia, lo strato verrà preso dalla cache.
Pietro: Perché parlate tutti di questi strati, copia tutto subito. Copia tutto. Nella prima riga.

Il Dockerfile ora appare così:

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

Pietro: Bene, cosa facciamo dopo? Hai le configurazioni per supervisor?
Vasiliy: No, non le ho. Ma le farò in fretta.
Pietro: Fallo dopo. Adesso mettiamo insieme uno script di init che avvierà tutto. Allora, inizia ad avviare ssh, con nohup, così possiamo connetterci al contenitore e vedere cosa non va. Poi avvia anche supervisor. E infine partirai semplicemente con passenger.
V: Ma ho letto che dovrebbe esserci un solo processo, così Docker saprà che qualcosa è andato storto e potrà riavviare il contenitore.
P: Non pensare a queste sciocchezze. E poi, come? Come avvii tutto in un solo processo? Lascia che pensi a stabilità Igor Ivanovich, non è per nulla che riceve uno stipendio. Il nostro compito è scrivere codice. E comunque, dovrebbe dirci grazie per aver scritto il Dockerfile per lui.

Dopo 10 minuti e due video di gatti.

V: Ho fatto tutto. Ho aggiunto anche qualche commento.
P: Fammi vedere!

Versione aggiornata del Dockerfile:

FROM ubuntu:latest

# Copia il codice sorgente
COPY . /app
WORKDIR /app

# Aggiorna la lista dei pacchetti
RUN apt-get update

# Aggiorna i pacchetti
RUN apt-get upgrade

# Installa i pacchetti necessari
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor

# Installa bundler
RUN gem install bundler

# Installa nodejs, necessario per la creazione della staticità
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs

# Installa le dipendenze
RUN bundle install --without development test --path vendor/bundle

# Pulisci la cache
RUN rm -rf /usr/local/bundle/cache/*.gem
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Esegui lo script all'avvio del contenitore, che avvierà tutto il resto.
CMD ["/app/init.sh"]

P: Ottimo, mi piace. E i commenti in russo, comodi e leggibili, tutti dovrebbero lavorare così. Ti ho insegnato tutto, ora puoi farlo da solo. Andiamo a bere un caffè…

Ecco, abbiamo ottenuto un Dockerfile terribilmente perfetto, che farebbe volere a Igor Ivanovich di licenziarsi e gli farà male gli occhi per un'altra settimana. Il Dockerfile, naturalmente, avrebbe potuto essere anche peggiore, non ci sono limiti al miglioramento. Ma per iniziare, va bene così.

Vorrei concludere con una citazione di Grigoriy Oster:

Se non avete ancora deciso
La strada da prendere nella vita,
E non sapete da dove
Iniziare il vostro percorso lavorativo,
Spegnete le lampadine nei pianerottoli —
La gente vi dirà "Grazie".
Aiuterete le persone
A risparmiare energia elettrica.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster