HowtoDocker : amélioration de la partie Dockerfile

This commit is contained in:
Romain Dessort 2018-05-10 15:54:12 -04:00
parent b809b6dc99
commit 8e3d689c54

View file

@ -337,30 +337,87 @@ Solutions:
## Dockerfile
Exemple :
Les fichiers _Dockerfile_ décrivent les étapes de construction d'une image. Ils
permettent de reconstruire à l'identique votre image et de connaitre exactement
ce qui a été fait. Ainsi au lieu de distribuer une image potentiellement
volumineuse, on distribue uniquement la procédure de construction
(_Dockerfile_) et les quelques fichiers annexes.
Référence pour la syntaxe des fichiers _Dockerfile_ : https://docs.docker.com/engine/reference/builder/
### Procédure de création d'une nouvelle image
Exemple avec une image exécutant rsyslog :
- depuis un répertoire vierge, création d'un fichier _Dockerfile_ :
~~~
~/docker-images/rsyslog $ $EDITOR Dockerfile
# Image sur laquelle notre image se base
FROM debian:stretch
MAINTAINER John Doe <jdoe@example.com>
# Champs optionnels
LABEL maintainer="John Doe <jdoe@example.com>"
# Installation des paquets voulus
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends rsyslog procps \
&& rm -rf /var/lib/apt/lists/*
RUN (apt-get update && apt-get upgrade -y -q && apt-get dist-upgrade -y -q && apt-get -y -q autoclean && apt-get -y -q autoremove)
RUN apt-get install -y -q mariadb-server
# Configuration de rsyslog. On peut modifier la configuration directement ou
# bien copier des fichiers de notre machine
RUN sed -i 's/^#\(module(load="imudp")\)/\1/; s/^#\(input(type="imudp" port="514")\)/\1/' /etc/rsyslog.conf
COPY custom.conf /etc/rsyslog.d/
EXPOSE 3306
CMD ["mysqld"]
# /var/log/ est un volume qui doit être monter depuis l'extérieur lors de
# l'exécution du conteneur
VOLUME /var/log/
# Le port 514/udp est rendu public à l'extérieur du conteneur à son exécution
EXPOSE 514/udp
# La commande suivante est exécutée lorsque le conteneur est exécuté
CMD /usr/sbin/rsyslogd -n
~~~
Dans la mesure du possible, voici quelques bonnes pratiques à respecter :
- la commande spécifiée par _CMD_ doit s'exécuter en avant plan et ne pas
forker. Si la commande rend la main, le conteneur sera alors arrêté ;
- la commande doit envoyer ses logs sur stdout et/ou stderr. Cela permet de
les consulter directement à l'aide de `docker logs`.
Un exemple à ne **pas** écrire :
~~~
CMD /usr/bin/foo -d; tail -f /var/log/foo.log
~~~
# ls
Dockerfile
# docker build -t mariadb .
Dans le cas où `/usr/bin/foo -d` lance le démon foo en arrière plan, le
conteneur s'exécutera correctement mais Docker va monitorer le processus tail
et non plus foo. Si foo crash, le conteneur ne passera pas en _failed_ et ne
pourra pas être redémarré automatiquement.
# docker images
À supposer que foo ne puisse pas envoyer ses logs sur stdout, le bon example
serait :
~~~
CMD touch /var/log/foo.log && tail -f /var/log/foo.log & /usr/bin/foo
~~~
À noter que seulement une seule directive `CMD` est acceptée dans un _Dockerfile_.
On peut ensuite construire notre image, en lui donnant ici le _tag_ _rsyslog_ :
~~~
~/docker-images/rsyslog $ ls
Dockerfile custom.conf
~/docker-images/rsyslog $ docker build -t rsyslog .
~/docker-images/rsyslog $ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
mariadb latest 4bea99cda08c 8 minutes ago 470MB
rsyslog latest 4bea99cda08c 8 minutes ago 470MB
debian stretch 5b712ae16dd7 3 days ago 100MB
~~~