Introduction¶
Docker est une plateforme open-source qui permet d’automatiser le déploiement d’applications à l’intérieur de conteneurs légers et portables
Un conteneur regroupe tout ce dont une application a besoin pour fonctionner : le code, les bibliothèques, les dépendances et le système d'exploitation léger
Cela permet de s’assurer que l’application fonctionne de manière cohérente, indépendamment de l’environnement
Concepts de base¶
- Images : Les images sont des instantanés d’applications. Elles sont immuables et servent de modèles pour les conteneurs. Elles sont créées à partir d’un Dockerfile
- Conteneurs : Les conteneurs sont des instances d’images qui tournent. Ils sont légers et portables
- Dockerfile : Un fichier texte qui contient les instructions pour construire une image Docker
Avantages de Docker¶
- Portabilité : Fonctionne de manière identique sur tous les environnements
- Isolation : Les conteneurs isolent l’application, ses dépendances et les processus
- Rapidité : Les conteneurs démarrent rapidement grâce à leur légèreté
- Scalabilité : Facile à mettre à l'échelle (scaler) en utilisant des systèmes d'orchestration comme Kubernetes
Création d'un Dockerfile¶
Un Dockerfile est un fichier texte qui contient une série d'instructions permettant de construire une image Docker
Explication des directives principales : - FROM : Spécifie l’image de base à utiliser (ex : Node.js, Python, Alpine) - WORKDIR : Définit le répertoire de travail à l’intérieur du conteneur - COPY : Copie les fichiers de l’hôte dans le conteneur - RUN : Exécute une commande pendant la construction de l’image - EXPOSE : Indique le port sur lequel l’application sera exposée - CMD : Spécifie la commande par défaut à exécuter lorsque le conteneur démarre
Structure d’un Dockerfile¶
Exemple pour une application Node.js (optimisé pour le cache des couches) :
# 1. Utiliser une version LTS récente
FROM node:20-alpine
# 2. Définir le répertoire de travail
WORKDIR /usr/src/app
# 3. Copier d'abord les fichiers de dépendances (optimisation cache)
COPY package*.json ./
# 4. Installer les dépendances
RUN npm ci
# 5. Copier le reste du code source
COPY . .
# 6. Exposer le port et démarrer
EXPOSE 3000
CMD ["node", "app.js"]
Optimisations possibles¶
Pour améliorer les performances et la taille de vos images Docker, voici quelques bonnes pratiques :
- Utilisation des images légères
Il est préférable d’utiliser des images de base légères, comme alpine, pour réduire la taille de l’image :
Cela permet de réduire considérablement la taille de l’image
Optimisations possibles¶
- Réduction du nombre de couches
Chaque instruction Docker crée une nouvelle couche. Pour réduire la taille des images, combinez les instructions RUN :
Optimisations possibles¶
- Nettoyage après installation
Lorsque vous installez des dépendances ou des outils, nettoyez les fichiers inutiles après :
Optimisations possibles¶
- Utilisation de multi-stage builds
Les multi-stage builds permettent de réduire la taille de l’image finale en ne conservant que les fichiers essentiels à l’exécution :
# Étape 1: Construction
FROM node:20-alpine as builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Étape 2: Production
FROM node:20-alpine
WORKDIR /usr/src/app
ENV NODE_ENV=production
COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/node_modules ./node_modules
CMD ["node", "dist/app.js"]
Bonnes pratiques¶
- Minimalisme : Essayez de garder vos images aussi petites que possible pour des raisons de performance et de sécurité
- Utilisez .dockerignore : Tout comme .gitignore, ce fichier permet d’exclure les fichiers inutiles (logs, node_modules locaux)
- Sécurité : Évitez d’inclure des secrets (clés API) dans le Dockerfile. Utilisez des variables d’environnement
- Versionner vos images : Utilisez des tags spécifiques et évitez le tag
latestpour garantir la reproductibilité - Testez vos images localement : Assurez-vous du bon fonctionnement avant de pousser vers un registre
Récap¶
Docker est un outil puissant pour le déploiement et la gestion d’applications dans des environnements isolés et reproductibles. En suivant les bonnes pratiques, il est possible de créer des images légères, performantes et sécurisées, tout en améliorant la portabilité de vos applications
Let's build !¶
Build Docker Image avec Docker-in-Docker (DinD)¶
Le principe du Docker-in-Docker (DinD) est de permettre d'exécuter Docker à l'intérieur d'un conteneur Docker
# .gitlab-ci.yml
stages:
- build
variables:
DOCKER_DRIVER: overlay2
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
services:
- docker:dind
build_image:
stage: build
image: docker:latest
script:
- docker info
- docker build -t my-app .
- docker images
- Services : GitLab CI démarre un démon Docker via le service
docker:dind - Variables :
DOCKER_HOSTpermet la communication avec le démon - Image Docker : Utilisation de l'image officielle
docker:latest - Script : La commande
docker buildconstruit l'image à partir du Dockerfile
Build Docker Image avec Kaniko¶
Kaniko construit des images Docker sans avoir besoin d'exécuter le démon Docker. C'est plus sécurisé (pas de mode privilégié) et idéal pour Kubernetes
# .gitlab-ci.yml
build_image:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- mkdir -p /kaniko/.docker
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor --dockerfile $CI_PROJECT_DIR/Dockerfile --context $CI_PROJECT_DIR --destination $IMAGE_NAME
- Sécurité : Pas besoin d'accès privilégié sur le Runner
- Authentification : Kaniko gère l'auth au registre via un fichier config.json injecté
- Performance : Build natif efficace dans des environnements conteneurisés
Benchmark¶
DinD (Docker-in-Docker) : - Plus simple et familier pour les utilisateurs de Docker - Nécessite souvent des privilèges élevés (risque sécurité) - Supporte bien le cache local si configuré proprement
Kaniko : - Plus sécurisé (rootless, pas de démon Docker) - Temps de construction légèrement supérieur - Solution recommandée pour les clusters Kubernetes (ex: GitLab Runners sur K8s)