
Dockle détecte les erreurs de configuration dans vos images Docker en vérifiant leur conformité avec le benchmark CIS Docker et les bonnes pratiques de sécurité. Contrairement à Trivy qui scanne les vulnérabilités des paquets, Dockle se concentre sur la construction de l’image : utilisateur root, secrets exposés, cache non nettoyé, absence de HEALTHCHECK. En 30 secondes, vous savez si votre image respecte les standards de sécurité.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer Dockle sur Linux ou macOS
- Analyser une image Docker et comprendre les résultats
- Interpréter les codes CIS (CIS-DI-0001, DKL-DI-0005, etc.)
- Personnaliser l’analyse avec les options essentielles
- Intégrer Dockle dans un pipeline CI/CD (GitLab CI, GitHub Actions)
- Corriger les problèmes les plus fréquents
Qu’est-ce que Dockle ?
Section intitulée « Qu’est-ce que Dockle ? »Dockle est un linter de sécurité pour images Docker. Il vérifie que votre image respecte les recommandations du CIS Docker Benchmark, un standard reconnu en sécurité des conteneurs.
Analogie : Dockle est à votre image Docker ce qu’un contrôle technique est à une voiture. Il ne vérifie pas si le moteur a des pièces défectueuses (vulnérabilités CVE — c’est le rôle de Trivy), mais si la voiture est bien configurée : ceintures présentes, freins fonctionnels, phares réglés.
Ce que Dockle vérifie
Section intitulée « Ce que Dockle vérifie »| Catégorie | Exemples de contrôles |
|---|---|
| Utilisateur | Image qui tourne en root ? |
| Secrets | Variables d’environnement sensibles (PASSWORD, TOKEN) ? |
| Fichiers | Clés SSH, certificats privés dans l’image ? |
| Cache | Cache apt/yum non nettoyé ? |
| Bonnes pratiques | HEALTHCHECK présent ? Tag latest utilisé ? |
Dockle vs Trivy vs Hadolint
Section intitulée « Dockle vs Trivy vs Hadolint »| Outil | Analyse | Quand l’utiliser |
|---|---|---|
| Dockle | Configuration de l’image finale | Après le build, avant le push |
| Trivy | Vulnérabilités des paquets (CVE) | Après le build, avant le push |
| Hadolint | Syntaxe du Dockerfile | Pendant l’écriture du Dockerfile |
Installation de Dockle
Section intitulée « Installation de Dockle »VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/')curl -L -o dockle.deb \ "https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.deb"sudo dpkg -i dockle.deb && rm dockle.debVERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/')sudo rpm -ivh \ "https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.rpm"Avec Homebrew :
brew install goodwithtech/r/dockleAvec apk :
VERSION=$( curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/')curl -L -o dockle.apk \ "https://github.com/goodwithtech/dockle/releases/download/v${VERSION}/dockle_${VERSION}_Linux-64bit.apk"apk add --allow-untrusted dockle.apk && rm dockle.apkVérification :
dockle --version# dockle version 0.4.15Premier scan avec Dockle
Section intitulée « Premier scan avec Dockle »Analyser une image
Section intitulée « Analyser une image »La commande de base est simple :
dockle NOM_IMAGE:TAGExemple avec une image problématique :
Voici un Dockerfile volontairement mal configuré :
FROM ubuntu:latestENV ADMIN_PASSWORD=secret123RUN apt-get update && apt-get install -y curlEXPOSE 8080CMD ["echo", "Hello"]Après construction (docker build -t test-bad:v1 .), le scan Dockle révèle :
dockle test-bad:v1FATAL - CIS-DI-0010: Do not store credential in environment variables/files * Suspicious ENV key found : ADMIN_PASSWORD on ENV ADMIN_PASSWORD=*******
FATAL - DKL-DI-0005: Clear apt-get caches * Use 'rm -rf /var/lib/apt/lists' after 'apt-get install|update'
WARN - CIS-DI-0001: Create a user for the container * Last user should not be root
INFO - CIS-DI-0005: Enable Content trust for Docker * export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO - CIS-DI-0006: Add HEALTHCHECK instruction to the container image * not found HEALTHCHECK statement
INFO - CIS-DI-0008: Confirm safety of setuid/setgid files * setuid file: urwxr-xr-x usr/bin/passwd * setuid file: urwxr-xr-x usr/bin/su [...] # Fichiers système normauxComprendre les niveaux de gravité
Section intitulée « Comprendre les niveaux de gravité »| Niveau | Signification | Action |
|---|---|---|
| FATAL | Faille de sécurité critique | Corriger obligatoirement |
| WARN | Configuration risquée | Corriger fortement recommandé |
| INFO | Amélioration possible | Évaluer selon le contexte |
| PASS | Contrôle réussi | Rien à faire |
Sortie JSON pour automatisation
Section intitulée « Sortie JSON pour automatisation »dockle --format json test-bad:v1{ "image": "test-bad:v1", "summary": { "fatal": 2, "warn": 1, "info": 3, "skip": 0, "pass": 10 }, "details": [ { "code": "CIS-DI-0010", "title": "Do not store credential in environment variables/files", "level": "FATAL", "alerts": [ "Suspicious ENV key found : ADMIN_PASSWORD on ENV ADMIN_PASSWORD=*******" ] } ]}Comprendre les codes de vérification
Section intitulée « Comprendre les codes de vérification »Dockle utilise deux familles de codes :
- CIS-DI-XXXX : Règles du CIS Docker Benchmark (standard industriel)
- DKL-DI-XXXX : Règles spécifiques à Dockle (bonnes pratiques)
Codes CIS les plus importants
Section intitulée « Codes CIS les plus importants »| Code | Règle | Comment corriger |
|---|---|---|
| CIS-DI-0001 | Ne pas utiliser root | Ajouter USER appuser |
| CIS-DI-0005 | Activer Content Trust | export DOCKER_CONTENT_TRUST=1 |
| CIS-DI-0006 | Ajouter HEALTHCHECK | HEALTHCHECK CMD curl -f http://localhost/ |
| CIS-DI-0008 | Vérifier setuid/setgid | Supprimer les bits avec chmod |
| CIS-DI-0010 | Pas de secrets en clair | Utiliser des secrets Docker ou variables d’exécution |
Codes Dockle spécifiques
Section intitulée « Codes Dockle spécifiques »| Code | Règle | Comment corriger |
|---|---|---|
| DKL-DI-0001 | Éviter sudo | Utiliser USER root puis USER appuser |
| DKL-DI-0002 | Éviter fichiers sensibles | Ajouter au .dockerignore |
| DKL-DI-0003 | Éviter latest | Utiliser un tag versionné |
| DKL-DI-0004 | Utiliser --no-cache (apk) | apk add --no-cache pkg |
| DKL-DI-0005 | Nettoyer le cache apt | rm -rf /var/lib/apt/lists/* |
| DKL-DI-0006 | Utiliser COPY plutôt que ADD | Remplacer ADD par COPY |
Options essentielles
Section intitulée « Options essentielles »Contrôler le code de sortie
Section intitulée « Contrôler le code de sortie »Par défaut, Dockle retourne toujours 0. Pour échouer en CI/CD :
# Échoue si WARN ou FATAL détectédockle --exit-code 1 mon-image:v1
# Échoue uniquement sur FATALdockle --exit-code 1 --exit-level FATAL mon-image:v1Ignorer des règles
Section intitulée « Ignorer des règles »Certaines règles peuvent ne pas s’appliquer à votre contexte :
# Ignorer une règle spécifiquedockle --ignore CIS-DI-0005 mon-image:v1
# Ignorer plusieurs règlesdockle -i CIS-DI-0005 -i CIS-DI-0008 mon-image:v1Personnaliser la détection de secrets
Section intitulée « Personnaliser la détection de secrets »Dockle détecte automatiquement les variables sensibles (PASSWORD, TOKEN, KEY…). Vous pouvez personnaliser cette détection :
# Accepter une variable normalement suspectedockle --accept-key GPG_KEY --accept-key CACHE_KEY mon-image:v1
# Ajouter des mots sensibles personnalisésdockle --sensitive-word api_secret --sensitive-word db_pass mon-image:v1
# Ajouter des fichiers sensibles personnalisésdockle --sensitive-file .git --sensitive-file .env mon-image:v1
# Ajouter des extensions sensibles personnaliséesdockle --sensitive-file-extension pfx --sensitive-file-extension p12 mon-image:v1Formats de sortie
Section intitulée « Formats de sortie »# Sortie par défaut (texte coloré)dockle mon-image:v1
# JSON pour parsing automatisédockle --format json mon-image:v1
# SARIF pour outils de sécurité (GitHub Security, SonarQube...)dockle --format sarif mon-image:v1 > dockle-results.sarifAnalyser une image distante
Section intitulée « Analyser une image distante »# Depuis un registre (nécessite authentification)dockle --username user --password pass registry.example.com/mon-image:v1
# Connexion non sécurisée (pour registres internes)dockle --insecure registry.internal:5000/mon-image:v1Intégration CI/CD
Section intitulée « Intégration CI/CD »GitLab CI
Section intitulée « GitLab CI »dockle_scan: stage: test image: docker:27.5 services: - docker:27.5-dind variables: DOCKLE_VERSION: "0.4.15" before_script: - apk add --no-cache curl - | curl -L -o /usr/local/bin/dockle \ "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit" - chmod +x /usr/local/bin/dockle script: - docker build -t $CI_PROJECT_NAME:$CI_COMMIT_SHA . - dockle --exit-code 1 --exit-level WARN $CI_PROJECT_NAME:$CI_COMMIT_SHA rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event"GitHub Actions
Section intitulée « GitHub Actions »name: Dockle Security Scan
on: push: branches: [main] pull_request: branches: [main]
jobs: dockle: runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v4
- name: Build image run: docker build -t app:${{ github.sha }} .
- name: Install Dockle env: DOCKLE_VERSION: "0.4.15" run: | curl -L -o dockle.deb \ "https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.deb" sudo dpkg -i dockle.deb
- name: Run Dockle run: dockle --exit-code 1 --format sarif -o dockle-results.sarif app:${{ github.sha }}
- name: Upload SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: dockle-results.sarifExemple de Dockerfile conforme
Section intitulée « Exemple de Dockerfile conforme »Voici un Dockerfile qui passe tous les contrôles Dockle :
FROM ubuntu:24.04
# Installer les dépendances et nettoyer le cacheRUN apt-get update && \ apt-get install -y --no-install-recommends curl && \ rm -rf /var/lib/apt/lists/*
# Créer un utilisateur non-rootRUN useradd -m -s /bin/bash appuser
WORKDIR /app
# Changer vers l'utilisateur non-rootUSER appuser
# Ajouter un healthcheckHEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:8080/health || exit 1
EXPOSE 8080CMD ["./app"]Résultat Dockle :
dockle app-conforme:v1INFO - CIS-DI-0005: Enable Content trust for Docker * export DOCKER_CONTENT_TRUST=1 before docker pull/build
INFO - CIS-DI-0008: Confirm safety of setuid/setgid files * setuid file: urwxr-xr-x usr/bin/passwd [...] # Fichiers système normaux de l'image de baseSeuls des INFO restent, liés à l’image de base Ubuntu. Aucun FATAL ni WARN.
Dépannage
Section intitulée « Dépannage »Problèmes courants
Section intitulée « Problèmes courants »| Symptôme | Cause probable | Solution |
|---|---|---|
FATAL CIS-DI-0010 | Variable sensible détectée | Utiliser --accept-key ou supprimer la variable |
FATAL DKL-DI-0005 | Cache apt non nettoyé | Ajouter rm -rf /var/lib/apt/lists/* |
WARN CIS-DI-0001 | Image tourne en root | Ajouter USER nonroot |
timeout exceeded | Image trop volumineuse | Utiliser --timeout 5m |
permission denied | Socket Docker inaccessible | Vérifier les droits sur /var/run/docker.sock |
Variables d’environnement
Section intitulée « Variables d’environnement »Toutes les options peuvent être passées via variables d’environnement :
| Variable | Équivalent option |
|---|---|
DOCKLE_IGNORES | --ignore |
DOCKLE_ACCEPT_KEYS | --accept-key |
DOCKLE_EXIT_CODE | --exit-code |
DOCKLE_EXIT_LEVEL | --exit-level |
DOCKLE_OUTPUT_FORMAT | --format |
DOCKLE_TIMEOUT | --timeout |
export DOCKLE_IGNORES="CIS-DI-0005,CIS-DI-0008"export DOCKLE_EXIT_CODE=1dockle mon-image:v1À retenir
Section intitulée « À retenir »-
Dockle analyse la configuration, pas les vulnérabilités — utilisez-le avec Trivy
-
FATAL et WARN doivent être corrigés avant mise en production
-
Toujours spécifier
--exit-code 1en CI/CD pour bloquer les images non conformes -
Pinnez la version de Dockle dans vos pipelines pour la reproductibilité
-
Utilisez
.dockleignorepour ignorer les règles non applicables à votre contexte -
Les codes CIS-DI sont des standards reconnus — leur respect facilite les audits de sécurité
-
Combinez Hadolint + Dockle + Trivy pour une couverture complète
Prochaines étapes
Section intitulée « Prochaines étapes »Plus d’infos
Section intitulée « Plus d’infos »Questions fréquentes
Section intitulée « Questions fréquentes »Dockle et Trivy sont complémentaires :
- Dockle analyse la configuration de l'image : utilisateur root, secrets exposés, cache non nettoyé, absence de HEALTHCHECK
- Trivy scanne les vulnérabilités CVE dans les paquets installés
Recommandation : utilisez les deux dans votre pipeline CI/CD pour une couverture complète.
Le CIS Docker Benchmark est un standard de sécurité reconnu publié par le Center for Internet Security. Il définit les bonnes pratiques pour sécuriser Docker :
- Ne pas exécuter les conteneurs en root
- Activer Docker Content Trust
- Ajouter des HEALTHCHECK
- Ne pas stocker de secrets dans l'image
Dockle vérifie automatiquement ces règles et les identifie par des codes CIS-DI-XXXX.
Dockle classe les problèmes par gravité :
| Niveau | Signification | Action |
|---|---|---|
| FATAL | Faille critique | Corriger obligatoirement |
| WARN | Configuration risquée | Corriger fortement recommandé |
| INFO | Amélioration possible | Évaluer selon contexte |
| PASS | Contrôle réussi | Rien à faire |
En CI/CD, utilisez --exit-code 1 pour bloquer sur FATAL/WARN.
Deux méthodes pour ignorer des règles :
1. En ligne de commande :
dockle --ignore CIS-DI-0005 -i CIS-DI-0008 mon-image:v1
2. Avec un fichier .dockleignore :
CIS-DI-0005
CIS-DI-0008
Dockle lira automatiquement ce fichier à la racine du projet.
L'intégration est simple :
- Installer Dockle dans le job (ou utiliser une image Docker pré-configurée)
- Builder l'image Docker
- Scanner avec
--exit-code 1pour échouer si des problèmes sont détectés
# GitLab CI exemple
script:
- docker build -t app:$CI_COMMIT_SHA .
- dockle --exit-code 1 app:$CI_COMMIT_SHA
Important : pinnez toujours la version de Dockle pour la reproductibilité.
L'erreur CIS-DI-0010 signifie que Dockle a détecté une variable d'environnement suspecte (PASSWORD, TOKEN, KEY...).
Solutions :
Supprimer la variable du Dockerfile et la passer au runtime :
docker run -e API_KEY=xxx mon-imageUtiliser Docker Secrets pour les données sensibles
Si la variable est un faux positif, l'accepter :
dockle --accept-key GPG_KEY mon-image:v1
L'erreur CIS-DI-0001 indique que votre image s'exécute en tant que root, ce qui est un risque de sécurité.
Correction : créez un utilisateur non-root dans votre Dockerfile :
# Créer un utilisateur
RUN useradd -m -s /bin/bash appuser
# Changer vers cet utilisateur (à la fin du Dockerfile)
USER appuser
Assurez-vous que l'instruction USER est après toutes les commandes nécessitant root (apt install, etc.).
L'erreur DKL-DI-0005 indique que le cache apt/yum n'a pas été nettoyé, ce qui alourdit l'image inutilement.
Correction : ajoutez le nettoyage dans la même instruction RUN :
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
Pour Alpine avec apk :
RUN apk add --no-cache curl
Dockle supporte le format SARIF (Static Analysis Results Interchange Format), compatible avec GitHub Security, SonarQube et d'autres outils.
dockle --format sarif -o dockle-results.sarif mon-image:v1
Dans GitHub Actions, uploadez le fichier avec :
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: dockle-results.sarif
Les résultats apparaîtront dans l'onglet Security de votre repo.
Dockle détecte automatiquement les fichiers sensibles courants (clés SSH, certificats). Depuis la version 0.4.15, les fichiers .env sont également détectés.
Pour ajouter vos propres fichiers sensibles :
# Fichiers spécifiques
dockle --sensitive-file .git --sensitive-file config.secret mon-image:v1
# Extensions spécifiques
dockle --sensitive-file-extension pfx --sensitive-file-extension p12 mon-image:v1
Ces options déclenchent une alerte si les fichiers sont trouvés dans l'image.