Creando un po' di immagini in Docker mi sono reso conto che è possibile avere un Dockerfile con una struttura che cambia poco tra un'immagine e l'altra in modo da avere un ambiente di "build" uniforme. Inoltre di solito faccio fare la maggior parte del lavoro a uno script di shell che viene eseguito nel containter invece che al Dockerfile; questo ha qualche vantaggio: si può utilizzare tutta la potenza della shell e si mantiene basso il numero di livelli. Tenete presente che Docker può gestire al massimo 127 livelli usando il devicemapper, mentre con AUFS il massimo scende a circa 42.
Struttura del Dockerfile
I miei Dockerfile sono divisi in quattro sezioni principali:
1) copia dei file nel container;
2) esecuzione del setup;
3) pubblicazione delle porte;
4) impostazione del comando di start.
Copia dei file
Come prima cosa si copiano tutti i file necessari nel container. Se i file sono numerosi è meglio chiuderli in un archivio tgz per avere il numero minore possibile di comandi "COPY": ricordatevi che ogni comando nel Dockerfile crea un nuovo livello, quindi è meglio eseguirne il minimo possibile.
Io uso /home come directory comoda in cui copiare i file temporanei.
Esecuzione dello script di setup
Il vero lavoro è svolto dallo script setup.sh che viene eseguito nel container e che può sfruttare i file copiati nel passaggio precedente.
Rimuovere lo script di setup non è strettamente indispensabile: potete lasciarlo dov'è.
Essendo uno script di shell setup.sh può fare molte cose, per esempio scompattare il tgz contenente il vostro sito web nella sua directory di destinazione, o cambiare i permessi del file start.sh per renderlo eseguibile, o installare ulteriori pacchetti con yum o apt-get, ecc.
Pubblicazione delle porte
Di solito il servizio che state predisponendo nel container usa delle porte per comunicare con l'esterno, quindi in ogni Dockerfile c'è qualche comando "EXPOSE".
Impostazione del comando di start
Il comando che avvia i miei container è sempre lo script start.sh, quindi anche questa parte del Dockerfile è sempre la stessa.
Conclusioni
A questo punto vi sarete resi conto che ci sono solo due parti del Dockerfile che cambiano:
1) i file che devono essere copiati;
2) le porte da esporre.
Tutto il resto non cambia. Ciò che cambia veramente da immagine a immagine sono gli script setup.sh e start.sh.
In realtà anche il mio script start.sh non cambia molto perché uso Monit per gestire i processi, quindi lo script è quasi sempre composto solo da questa riga:
Sull'utilizzo di Monit all'interno di un container ho pubblicato un articolo specifico.
Struttura del Dockerfile
I miei Dockerfile sono divisi in quattro sezioni principali:
1) copia dei file nel container;
2) esecuzione del setup;
3) pubblicazione delle porte;
4) impostazione del comando di start.
Copia dei file
Come prima cosa si copiano tutti i file necessari nel container. Se i file sono numerosi è meglio chiuderli in un archivio tgz per avere il numero minore possibile di comandi "COPY": ricordatevi che ogni comando nel Dockerfile crea un nuovo livello, quindi è meglio eseguirne il minimo possibile.
COPY ./website.tgz /home/ ADD ./start.sh /start.sh
Io uso /home come directory comoda in cui copiare i file temporanei.
Esecuzione dello script di setup
Il vero lavoro è svolto dallo script setup.sh che viene eseguito nel container e che può sfruttare i file copiati nel passaggio precedente.
ADD ./setup.sh /setup.sh RUN /bin/bash /setup.sh
RUN rm -f /setup.sh
Rimuovere lo script di setup non è strettamente indispensabile: potete lasciarlo dov'è.
Essendo uno script di shell setup.sh può fare molte cose, per esempio scompattare il tgz contenente il vostro sito web nella sua directory di destinazione, o cambiare i permessi del file start.sh per renderlo eseguibile, o installare ulteriori pacchetti con yum o apt-get, ecc.
yum -y -q install tar
[ -d /srv ] || mkdir -m 755 /srv
cd /srv
tar xzf /home/website.tgz
rm /home/website.tgz
chmod 755 /start.sh
Pubblicazione delle porte
Di solito il servizio che state predisponendo nel container usa delle porte per comunicare con l'esterno, quindi in ogni Dockerfile c'è qualche comando "EXPOSE".
EXPOSE 8100
EXPOSE 8101
Impostazione del comando di start
Il comando che avvia i miei container è sempre lo script start.sh, quindi anche questa parte del Dockerfile è sempre la stessa.
CMD [ "/bin/bash", "/start.sh" ]
Conclusioni
A questo punto vi sarete resi conto che ci sono solo due parti del Dockerfile che cambiano:
1) i file che devono essere copiati;
2) le porte da esporre.
Tutto il resto non cambia. Ciò che cambia veramente da immagine a immagine sono gli script setup.sh e start.sh.
In realtà anche il mio script start.sh non cambia molto perché uso Monit per gestire i processi, quindi lo script è quasi sempre composto solo da questa riga:
monit -l - -c /etc/monit.conf
Sull'utilizzo di Monit all'interno di un container ho pubblicato un articolo specifico.
Commenti
Posta un commento