Instructions avancées pour les Dockerfile
Dans cette étape finale, nous allons explorer quelques instructions supplémentaires pour les Dockerfile et les meilleures pratiques qui peuvent aider à rendre vos images Docker plus sécurisées, maintenables et plus faciles à utiliser. Nous nous concentrerons également sur la résolution de problèmes et la vérification de chaque étape du processus.
-
Dans WebIDE, réouvrez le fichier Dockerfile
.
-
Remplacez le contenu par le suivant :
## Build stage
FROM python:3.9-slim AS builder
WORKDIR /app
COPY requirements.txt.
RUN pip install --user --no-cache-dir -r requirements.txt
## Final stage
FROM python:3.9-slim
## Create a non-root user
RUN useradd -m appuser
## Install curl for healthcheck
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
WORKDIR /app
## Dynamically determine Python version and site-packages path
RUN PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') && \
SITE_PACKAGES_PATH="/home/appuser/.local/lib/python${PYTHON_VERSION}/site-packages" && \
mkdir -p "${SITE_PACKAGES_PATH}" && \
chown -R appuser:appuser /home/appuser/.local
## Copy site-packages and binaries using the variable
COPY --from=builder /root/.local/lib/python3.9/site-packages "${SITE_PACKAGES_PATH}"
COPY --from=builder /root/.local/bin /home/appuser/.local/bin
COPY app.py.
ENV PATH=/home/appuser/.local/bin:$PATH
ENV ENVIRONMENT=production
## Set the user to run the application
USER appuser
## Use ENTRYPOINT with CMD
ENTRYPOINT ["python"]
CMD ["app.py"]
EXPOSE 5000
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:5000/ || exit 1
ARG BUILD_VERSION
LABEL maintainer="Your Name <[email protected]>"
LABEL version="${BUILD_VERSION:-1.0}"
LABEL description="Flask app demo with advanced Dockerfile techniques"
Analysons les nouveaux concepts introduits dans ce Dockerfile :
RUN useradd -m appuser
: Cette commande crée un nouvel utilisateur nommé appuser
dans le conteneur. Exécuter des applications en tant qu'utilisateur non-root est une bonne pratique de sécurité, car cela limite les dommages potentiels en cas de compromission de l'application. Le flag -m
crée un répertoire personnel pour l'utilisateur.
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
: Cette commande installe le paquet curl, qui est nécessaire pour que l'instruction HEALTHCHECK fonctionne. Nous nettoyons également le cache apt pour réduire la taille de l'image.
RUN PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') &&...
: Cet ensemble de commandes détermine dynamiquement la version de Python dans le conteneur et crée le répertoire site-packages
correct pour l'utilisateur appuser
. Il définit également les bonnes permissions pour le répertoire local de l'utilisateur.
COPY --from=builder /root/.local/lib/python3.9/site-packages "${SITE_PACKAGES_PATH}"
: Cette instruction copie les paquets Python installés depuis l'étape builder
vers le chemin site-packages
déterminé dynamiquement dans l'image finale, garantissant que les paquets sont placés au bon endroit pour que l'utilisateur appuser
puisse les utiliser.
COPY --from=builder /root/.local/bin /home/appuser/.local/bin
: Cette commande copie les scripts exécutables installés par pip
(comme l'interface en ligne de commande de Flask, le cas échéant) depuis l'étape builder
vers le répertoire bin
local de l'utilisateur appuser
.
ENTRYPOINT ["python"]
avec CMD ["app.py"]
: Lorsqu'ils sont utilisés ensemble, ENTRYPOINT
définit l'exécutable principal du conteneur (dans ce cas, python
), et CMD
fournit les arguments par défaut pour cet exécutable (app.py
). Ce modèle offre de la flexibilité : les utilisateurs peuvent exécuter le conteneur et exécuter app.py
par défaut, ou ils peuvent remplacer CMD
pour exécuter d'autres scripts Python ou commandes.
HEALTHCHECK
: Cette instruction configure un contrôle d'intégrité pour le conteneur. Docker exécutera périodiquement la commande spécifiée (curl -f http://localhost:5000/
) pour déterminer si le conteneur est en bonne santé. Les flags --interval=30s
et --timeout=3s
définissent respectivement l'intervalle de vérification et le délai d'attente. Si la commande curl
échoue (renvoie un code de sortie non nul), le conteneur est considéré comme en mauvaise santé.
ARG BUILD_VERSION
: Cela définit un argument de construction nommé BUILD_VERSION
. Les arguments de construction vous permettent de passer des valeurs dans l'image Docker au moment de la construction.
LABEL version="${BUILD_VERSION:-1.0}"
: Cela définit une étiquette nommée version
sur l'image Docker. Il utilise l'argument de construction BUILD_VERSION
. Si BUILD_VERSION
est fourni lors de la construction, sa valeur sera utilisée ; sinon, il prend la valeur par défaut 1.0
(en utilisant la syntaxe de valeur par défaut :-
).
- Maintenant, construisons cette nouvelle image en spécifiant une version de construction :
docker build -t advanced-flask-app-v2 --build-arg BUILD_VERSION=2.0.
Le flag --build-arg BUILD_VERSION=2.0
nous permet de passer la valeur 2.0
pour l'argument de construction BUILD_VERSION
lors du processus de construction de l'image. Cette valeur sera utilisée pour définir l'étiquette version
dans l'image Docker.
- Une fois la construction terminée, vérifions que l'image a été créée avec succès :
docker images | grep advanced-flask-app-v2
Vous devriez voir la nouvelle image advanced-flask-app-v2
répertoriée dans la sortie de la commande docker images
, ainsi que son étiquette, son ID d'image, sa date de création et sa taille.
- Maintenant, exécutons un conteneur avec la nouvelle image :
docker run -d -p 5002:5000 --name advanced-container-v2 advanced-flask-app-v2
Cette commande exécute un conteneur en mode détaché (-d
), mappe le port 5002 de votre hôte sur le port 5000 du conteneur (-p 5002:5000
), nomme le conteneur advanced-container-v2
(--name advanced-container-v2
) et utilise l'image advanced-flask-app-v2
pour créer le conteneur.
- Vérifions que le conteneur est en cours d'exécution :
docker ps | grep advanced-container-v2
Si le conteneur s'exécute avec succès, vous devriez le voir répertorié dans la sortie de la commande docker ps
. Si vous ne voyez pas le conteneur répertorié, il peut avoir été arrêté. Vérifions s'il y a des conteneurs arrêtés :
docker ps -a | grep advanced-container-v2
Si vous voyez le conteneur répertorié dans la sortie de docker ps -a
mais qu'il n'est pas en cours d'exécution (le statut n'est pas "Up"), nous pouvons vérifier ses journaux pour détecter les erreurs :
docker logs advanced-container-v2
Cette commande affichera les journaux du conteneur advanced-container-v2
, ce qui peut aider à diagnostiquer les problèmes de démarrage ou les erreurs d'exécution de votre application Flask.
- En supposant que le conteneur soit en cours d'exécution, après avoir laissé un peu de temps au conteneur pour démarrer, nous pouvons vérifier son statut de santé :
docker inspect --format='{{.State.Health.Status}}' advanced-container-v2
Après un court délai (pour permettre au contrôle d'intégrité de s'exécuter au moins une fois), vous devriez voir "healthy" comme sortie. Si vous voyez "unhealthy" au départ, attendez 30 secondes supplémentaires (l'intervalle de contrôle d'intégrité) et exécutez à nouveau la commande. Si le statut reste "unhealthy", vérifiez les journaux du conteneur en utilisant docker logs advanced-container-v2
pour détecter d'éventuels problèmes avec votre application Flask. Si il n'y a pas de problèmes évidents, vous pouvez ignorer le statut "unhealthy".
- Nous pouvons également vérifier que l'étiquette de version de construction a été correctement appliquée :
docker inspect -f '{{.Config.Labels.version}}' advanced-flask-app-v2
Cette commande récupère la valeur de l'étiquette version
de l'image advanced-flask-app-v2
et l'affiche. Vous devriez voir "2.0" comme sortie, ce qui confirme que l'argument de construction BUILD_VERSION
a été correctement utilisé pour définir l'étiquette.
- Enfin, testons notre application en lui envoyant une requête :
curl http://localhost:5002
Vous devriez voir le message "Hello from production environment!" dans la sortie. Cela indique que votre application Flask s'exécute correctement à l'intérieur du conteneur Docker et est accessible sur le port 5002 de votre hôte.
Ces techniques avancées vous permettent de créer des images Docker plus sécurisées, configurables et prêtes pour la production. L'utilisation d'un utilisateur non-root améliore la sécurité, le HEALTHCHECK
facilite l'orchestration et la surveillance des conteneurs, et les arguments de construction permettent de construire des images plus flexibles et versionnées.