
Quando stavo imparando a guidare, al primo lezione l'istruttore è uscito in retromarcia all'incrocio e poi ha detto che non si deve mai fare una cosa del genere. Questa regola l'ho subito memorizzata e mi è rimasta per tutta la vita.
Leggi ai bambini 'Consigli nocivi' di Grigorij Oster e vedi quanto facilmente e naturalmente capiscono che non si deve fare in quel modo.
Ci sono tonnellate di articoli su come scrivere correttamente un Dockerfile. Ma non ho mai trovato istruzioni su come scrivere un Dockerfile sbagliato. Colmo questa lacuna. E forse nei progetti che gestisco ce ne saranno meno di questi Dockerfile.
Tutti i personaggi, le situazioni e i Dockerfile sono inventati. Se ti riconosci, scusa.
Creiamo un Dockerfile, sinistro e terribile
Pietro (Senior java/ruby/php developer): Collega Vasily, hai già caricato il nuovo modulo in Docker?
Vasily (junior): No, non ho fatto in tempo, non riesco a capire questo Docker. Ci sono così tanti articoli, mi confondo.
Pietro: La nostra scadenza è scaduta un anno fa. Fammi aiutare, vediamo di capire. Raccontami cos'è che non riesci a fare.
Vasily: Non riesco a scegliere l'immagine di base, vorrei una minima, ma con tutto il necessario.
Pietro: Prendi l'immagine di ubuntu, ha tutto quello che serve. eventuale ciò che è in più potrebbe tornare utile in seguito. E non dimenticare di mettere il tag latest, così avrai sempre l’ultima versione.
E nel Dockerfile appare la prima riga:
FROM ubuntu:latestPietro: Cosa c'è dopo, su cosa abbiamo scritto il nostro modulo?
Vasily: È ruby, giusto? Dovrebbe avviarsi un server web e un paio di demoni di servizio.
Pietro: Ok, allora abbiamo bisogno di: ruby, bundler, nodejs, imagemagick e magari anche altro... Inoltre, fai un upgrade per essere sicuro di ottenere i pacchetti più recenti.
Vasily: Non creeremo un utente, così non lavoriamo come root?
Pietro: Lascia perdere, poi dovremo tenere d’occhio i permessi.
Vasily: Ho bisogno di tempo, circa 15 minuti, per mettere tutto insieme in un solo comando. Ho letto che...
(Pietro interrompe bruscamente il curioso e troppo intelligente junior.)
Pietro: 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/*In quel momento irrompe Igor Ivanovich, DevOps (ma più Ops che Dev), urlando:
II: Petya, i tuoi sviluppatori hanno di nuovo distrutto il database di produzione, quando finirà tutto questo....
Dopo una piccola discussione, Igor Ivanovich si calma e inizia a capire cosa stanno facendo i colleghi.
II: Di cosa siete occupati?
Vasily: Pietro mi sta aiutando a scrivere un Dockerfile per un nuovo modulo.
II: Fatemi vedere... Ma cosa avete scritto qui, pulite il repository con un comando separato, questo è uno strato aggiuntivo... Come installate le dipendenze se non avete copiato il Gemfile! E soprattutto, non si può usare una cosa simile.
Pietro: Per favore, occupati dei tuoi affari, noi ce la caveremo.
Igor Ivanovich sospira tristemente e se ne va a capire chi ha rotto il database.
Pietro: Sì, ma ha ragione sul codice, dobbiamo inserirlo nell'immagine. E mettiamoci subito anche ssh e supervisor, altrimenti come lanceremo i demoni?
Vasily: Allora prima copierò il Gemfile e il Gemfile.lock, poi installerò tutto e infine copierò l'intero progetto. Se il Gemfile non cambia, lo strato sarà prelevato dalla cache.
Pietro: Perché vi preoccupate di questi strati? Copia tutto subito. Copia subito. Come prima cosa.
Ora il Dockerfile 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: Allora, cosa c'è dopo? Hai file di configurazione per il supervisor?
Vasily: No, non ce li ho. Ma lo farò in fretta.
Pietro: Lo farai poi. Ora scriviamo uno script di init che avvii tutto. Quindi avvia ssh con nohup, così possiamo collegarci al container e vedere cosa è andato storto. Poi avvia anche il supervisor in modo simile. E poi avvierai semplicemente passenger.
V: Ma ho letto che deve esserci un solo processo, così Docker saprà che qualcosa è andato storto e potrà ripristinare il container.
P: Non ti preoccupare di queste sciocchezze. E comunque, come? Come lancerai tutto in un solo processo? Lascia che a pensare alla stabilità ci pensi Igor Ivanovich, non per niente guadagna uno stipendio. Il nostro compito è scrivere codice. Inoltre, dovrebbe dirci grazie per aver scritto il Dockerfile per lui.
Dopo 10 minuti e due video di gattini.
V: Ho finito. Ho aggiunto anche alcuni commenti.
P: Mostrami!
Nuova versione del Dockerfile:
FROM ubuntu:latest
# Copiamo il codice sorgente
COPY ./ /app
WORKDIR /app
# Aggiorniamo l'elenco dei pacchetti
RUN apt-get update
# Aggiorniamo i pacchetti
RUN apt-get upgrade
# Installiamo i pacchetti necessari
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor
# Installiamo bundler
RUN gem install bundler
# Installiamo nodejs utilizzato per la raccolta di statici
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
# Installiamo le dipendenze
RUN bundle install --without development test --path vendor/bundle
# Pulisci i cache
RUN rm -rf /usr/local/bundle/cache/*.gem
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Eseguiamo lo script all'avvio del contenitore, che avvierà 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 farcela da solo. Andiamo a bere un caffè…
Ecco, abbiamo ottenuto un Dockerfile perfettamente orrendo, la vista del quale farà venire voglia di licenziarsi a Igor Ivanovich e per una settimana gli darà fastidio agli occhi. Certo, il Dockerfile potrebbe essere ancora peggio, non ci sono limiti alla perfezione. Ma per cominciare, va bene così.
Vorrei concludere con una citazione di Grigorij Oster:
Se non avete ancora deciso
In vita la strada da prendere,
E non sapete da dove
Iniziare il vostro cammino lavorativo,
Spaccate le lampadine nei pianerottoli —
La gente vi dirà «Grazie».
Aiuterete le persone
A risparmiare elettricità.
Fonte: habr.com
