Dans cet article, nous explorerons des moyens avancés d'optimiser un Dockerfile pour une application Python, visant à le rendre plus adapté à la production. Suivez ces six étapes pour garantir une meilleure sécurité, performance et convivialité de votre Dockerfile.
1. Ajouter un identifiant de commit Git
Marquons chaque image Docker et conteneur avec un tag représentant le hash du commit Git. Ceci permet de retracer facilement la version du logiciel en cours d'exécution. Utilisez les instructions ARG et ENV pour définir ces variables dans le Dockerfile.
FROM python:3.8.3-slim-buster
COPY . /src
# 👇
ARG GIT_HASH
ENV GIT_HASH=${GIT_HASH:-dev}
# 👆
RUN pip install -r /src/requirements.txt
Utilisez docker build --build-arg GIT_HASH=<hash>
pour spécifier le hash du commit lors de la construction de l'image.
2. Ajouter un répertoire de travail
Améliorez la lisibilité en spécifiant un répertoire de travail avec l'instruction WORKDIR. Cela simplifie l'utilisation des chemins dans les commandes ultérieures.
FROM python:3.8.3-slim-buster
# 👇
WORKDIR /project
# 👇
COPY . .
ARG GIT_HASH
ENV GIT_HASH=${GIT_HASH:-dev}
# 👇
RUN pip install -r requirements.txt
Désormais, toutes les instructions suivantes utiliseront ce répertoire comme base.
3. Mettre en cache les dépendances
Optimisez le processus de construction en mettant en cache les dépendances. Copiez d'abord le fichier requirements.txt et installez les dépendances avant de copier le reste du code.
FROM python:3.8.3-slim-buster
WORKDIR /project
COPY requirements.txt ./
# 👇
RUN pip install -r requirements.txt
# 👆
ARG GIT_HASH
ENV GIT_HASH=${GIT_HASH:-dev}
COPY . .
Cela permet de conserver la mise en cache lors de modifications mineures du code.
4. Exécuter le conteneur en tant qu'utilisateur non root
Améliorez la sécurité en créant et utilisant un nouvel utilisateur non root dans le conteneur.
FROM python:3.8.3-slim-buster
WORKDIR /project
# 👇
RUN useradd -m -r user && \
chown user /project
# 👆
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
# 👇
USER user
Cela réduit les risques de sécurité en limitant les privilèges du conteneur.
5. Gérer les processus zombie et les signaux
Utilisez Tini comme init pour résoudre les problèmes liés aux processus zombie et au transfert correct des signaux.
FROM python:3.8.3-slim-buster
# 👇
ENV TINI_VERSION="v0.19.0"
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
# 👆
WORKDIR /project
RUN useradd -m -r user && \
chown user /project
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
# 👇
ENTRYPOINT ["/tini", "--"]
Tini garantit un arrêt propre de l'application en transférant correctement les signaux.
6. Mettre à jour pip, setuptools et wheel
Assurez-vous de maintenir à jour pip, setuptools et wheel directement dans l'image Docker.
FROM python:3.8.3-slim-buster
ENV TINI_VERSION="v0.19.0"
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
# 👇
RUN pip install -U \
pip \
setuptools \
wheel
# 👆
WORKDIR /project
RUN useradd -m -r user && \
chown user /project
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
ENTRYPOINT ["/tini", "--"]
Cette approche garantit que les outils essentiels restent à jour, renforçant la sécurité et la stabilité de l'environnement Docker.
Avec ces améliorations, notre Dockerfile devient plus robuste, sécurisé et performant, prêt à être utilisé dans des environnements de production exigeants. En suivant ces étapes, vous pouvez créer une base solide pour vos applications Python conteneurisées.