Ceci est une ancienne révision du document !
L'objectif est de créer une image Docker qui permettra de faire fonctionner un conteneur avec notre application.
L'idée est de partir sur un système de base, d'y inclure les prérequis de notre application, installer notre application et les commandes pour exécuter notre application au lancement du conteneur.
Les bonnes pratiques pour créer une image sont les suivantes :
digest
pour cibler la version à déployerRUN
pour éviter de surcharger la taille de l'imageapt update -qq && apt install -qq -y apache2 && apt clean && rm -rf /var/lib/apt/lists/*
.telnet
, tcpdump
..dockerignore
pour exclure des fichiers de la copie. Exclure par exemple le Dockerfile
.COPY
plutôt que ADD
.ADD
uniquement pour télécharger des contenus externes au dossier dédiéCOPY . .
root
root
au lancement de l'application du conteneur.ENV
WORKDIR
En exemple, Nous allons simplement créer une image contenant un serveur Web apache basé sur une image Debian.
Pour commencer, créer un dossier de travail et aller dedans :
mkdir myapp cd myapp
Créer dans le dossier créer un fichier '.dockerignore' et on ajouter la ligne suivante pour ignorer le fichier Dockerfile
:
Dockerfile
On va créer un dossier app
et y mettre une page html.
mkdir app echo "Apache dans conteneur" > app/index.html
Créer le Dockerfile suivant :
vim Dockerfile
Contenu en exemple :
# Source pour l'image de base FROM debian:bullseye-slim # On peut également cibler l'image ainsi avec le Digest SHA256 #FROM debian@sha256:9af4db29e828a4d08c7819f9e0972e2dbdac575e73c6438630c83bd79f49c8aa # Labels pour identifier notre image LABEL version=1.0 LABEL auteur=Benoit # On défini quelque variable d'environnement au sein du conteneur ENV APP_ENV="PreProd" ENV APP_NAME="MyWEB" ENV APP_VER="1.0" # On définir des variable à utilsier dans le Dockerfile ARG APP_USER="benoit" # Création de l'utilisateur RUN adduser ${APP_USER} # Intallation des paquetages requis # A noter qu'on lance l'installation et le nettoyage d'APT pour éviter de surcharger notre image par des Layers RUN apt update && apt install -y apache2 && apt clean && rm -rf /var/lib/apt/lists/*
# On execute les prerequis pour lancer notre serveur Apache2 RUN mkdir -p /var/run/apache2 && . /etc/apache2/envvars # On lance apache2 CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"] # Répertoire de travail de l'App WORKDIR /var/www/html # Ci-dessous la directive pour faire tourner l'application autre que root #USER ${APP_USER} # On copie les fichiers locaux sur le WORKDIR du conteneur COPY app/* . # Exemple ci-dessous en spécifiant les permissions #COPY --chown=${APP_USER} app/* . # On expose le port 80 EXPOSE 80
Lancer le build de l'image
docker build -t webapp:v1 .
Pour lancer un conteneur à partir de notre image :
docker run -d --name c1 -p 8080:80 webapp:v1
Le build multistage permet de reprendre des éléments d'une autre image pour créer l'image.
# Build 0 FROM debian:latest # On crée un fichier /var/toto.1 RUN echo "toto" > /var/toto.1 # Build 1 # On peut définir un alias par exemple b1 pour la source FROM debian:latest AS b1 # On crée le fichier /var/toto.2 RUN echo "toto" > /var/toto.2 # On recopie à partir du build 0 le fichier /var/toto.1 que l'on copie dans / COPY --from=0 /var/toto.1 / # Build 2 FROM debian:latest # On crée le fichier /var/toto.3 RUN echo "toto" > /var/toto.3 # On recopie à partir du build 1 le fichier /var/toto.2 que l'on copie dans / en indiquant l'alias en source COPY --from=b1 /var/toto.2 / # On peut aussi copier un fichier depuis une image existante COPY --from=httpd:latest /usr/local/apache2/conf/httpd.conf /etc
On final dans ce build on retrouvera uniquement les fichiers suivants :
/toto.2
/var/toto.3
/etc/httpd.conf
Le Dockerfile :
# DECLARATION VARIABLE POUR LE BUILD AVEC VALEUR PAR DEFAUT ARG TYPE=development # IMAGE DE BASE FROM debian:latest AS base RUN echo "Base" > /var/info.txt # IMAGE AVEC LES ELEMENTS DE DEV FROM base AS branch-version-development # Tous les élements requis pour l'environnement de Dev RUN echo "dev" >> /var/info.txt ENV ENV=development # IMAGE AVEC LES ELEMENTS DE PROD FROM base AS branch-version-production # Tous les élements requis pour l'environnement de Prod RUN echo "production" >> /var/info.txt ENV ENV=production # IMAGE AVEC LES ELEMENTS DE DEV OU PROD EN FONCTION DE LA VARIABLE TYPE FROM branch-version-${TYPE} AS final UN echo "fin" >> /var/info.txt
Si on souhaite créer une image avec les éléments de dev :
docker build -t myapp:v1 --build-arg TYPE=development .
Et pour la prod :
docker build -t myapp:v1 --build-arg TYPE=production .
On peut aussi lancer le build de la base uniquement :
docker build -t myapp:v1 --target base