Les Dockerfiles définissent le contenu des images Docker comme un ensemble d’instructions dans un fichier texte. La syntaxe des Dockerfiles est généralement simple, mais il y a quelques pièges à éviter. Le respect des bonnes pratiques lors de l’écriture de Dockerfiles complexes en équipe peut s’avérer délicat, sauf si vous validez automatiquement le contenu de votre fichier.

Hadolint est un linter de fichier Docker qui peut repérer les problèmes courants pour vous. Il utilise un arbre syntaxique abstrait (AST) pour analyser votre fichier Docker en fonction de règles prédéfinies. Hadolint intègre également ShellCheck, ce qui lui permet de vérifier les scripts shell dans les instructions RUN de votre fichier Docker.

Mise en route

Hadolint est distribué en plusieurs formats. Vous pouvez commencer rapidement en téléchargeant le dernier binaire précompilé pour votre système d’exploitation à partir de la page des versions GitHub du projet.

Hadolint dispose également de sa propre image Docker, hadolint/hadolint, si vous préférez ne pas utiliser le binaire directement. Enfin, vous pouvez accéder à Hadolint via le Web à des fins d’expérimentation.

Linting d’un fichier Docker

Passez à Hadolint le chemin vers un Dockerfile pour commencer une nouvelle analyse :

hadolint Dockerfile

Si vous utilisez la version Dockerisée, le plus simple est de placer le contenu de votre fichier dans un conteneur Hadolint :

docker run –rm -i hadolint/hadolint < Dockerfile

Les résultats de l’analyse s’afficheront dans votre terminal. Dans cet exemple, Hadolint suggère que l’instruction RUN apt-get install du Dockerfile n’est pas sûre car elle ne spécifie pas de versions explicites des paquets. Le contenu de votre image pourrait changer entre deux constructions, ce qui pourrait créer des problèmes de confusion.

Que recherche Hadolint ?

Hadolint possède des dizaines de règles intégrées qui vérifient les problèmes de configuration et de sécurité courants. Le linter vise à rendre vos fichiers Docker conformes aux meilleures pratiques de construction d’images suggérées par Docker.

Les vérifications incluses couvrent l’utilisation d’utilisateurs finaux non root, la référence à un chemin relatif dans une déclaration WORKDIR, l’ajout d’instructions HEALTHCHECK multiples et la non-utilisation de balises et de versions explicitement épinglées. Comme Hadolint hérite également du jeu de règles de ShellCheck, il détectera les problèmes courants de script Bash que cet outil identifie également.

Les règles sont identifiées par des numéros préfixés par HL ou SC. Les règles HL font partie de Hadolint tandis que les entrées SC proviennent de ShellCheck. Chaque vérification reçoit un degré de gravité allant d’Erreur à Info. Si vous obtenez des erreurs dans les résultats de votre analyse, vous devez résoudre ces problèmes en premier.

Personnalisation de la configuration

Hadolint est configuré via un fichier .hadolint.yaml. Il recherchera plusieurs emplacements, y compris vos répertoires de travail, .config et personnel. Seul le premier fichier trouvé est utilisé – il n’y a pas de fusion entre les emplacements.

Le fichier de configuration vous permet de personnaliser vos analyses en ignorant des règles et en modifiant leur sévérité. Bien que le jeu de règles par défaut couvre les meilleures pratiques recommandées, vous pouvez trouver que certaines vérifications ne s’appliquent pas dans votre environnement. L’ajout d’un fichier .hadolint.yaml à votre Dockerfile vous permet d’adapter les analyses Hadolint en conséquence. La plupart des champs du fichier de configuration sont également pris en charge en tant que drapeaux CLI et variables d’environnement.

Les règles sont désactivées par le champ ignoré. Il doit s’agir d’une liste d’ID de règles :

ignoré :

  • DL3010
  • DL3020

Si vous devez réduire la gravité d’une règle sans la désactiver complètement, utilisez plutôt la touche « override ». Cette touche vous permet également de faire passer un problème de faible gravité à un niveau supérieur. Utilisez cette option si vous souhaitez mettre l’accent sur un problème particulier.

Remplacer :
avertissement :
– DL3020

Cette option rétrograde la règle DL3020 du niveau « erreur » par défaut au niveau « avertissement », moins grave. Cette règle exige que vous utilisiez COPY au lieu de ADD lorsque vous faites référence à des fichiers et des dossiers dans votre contexte de construction.

Vous pouvez également ajuster le niveau de gravité global. La définition du champ failure-threshold indique à Hadolint de sortir avec un statut d’échec si un test rapporte une erreur au niveau de gravité donné :

failure-threshold : warning

Cette instruction signifie que l’analyse Hadolint échouera s’il y a une erreur ou un avertissement dans sa sortie.

Vous pouvez désactiver la sortie avec un code d’échec en utilisant l’option de configuration no-fail : true ou l’indicateur CLI –no-fail. Cela demandera à Hadolint de sortir avec un code 0, quel que soit le résultat réel du test. Cela peut être utile si vous voulez inclure Hadolint comme tâche non bloquante dans un pipeline CI.

Faire confiance aux registres

Une autre utilisation du fichier de configuration consiste à définir les registres de confiance que vous souhaitez pouvoir référencer dans vos Dockerfiles. Lorsque le champ trustedRegistries est défini, Hadolint vous avertit lorsqu’une image provenant d’un autre registre est utilisée :

trustedRegistries :

  • docker.io
  • docker-registry.example.com

Schémas d’étiquettes

Hadolint offre également un linting de base pour les étiquettes. Cela vous permet d’imposer que les étiquettes ajoutées à votre image par les instructions Dockerfile LABEL respectent les contraintes spécifiées. Voici un exemple de son fonctionnement :

label-schema :
notes : texte
app-version : semver
built-at : rfc3339

Cet extrait de configuration définit les types de données pour quatre étiquettes que vous pouvez utiliser dans votre Dockerfile. notes est déclaré comme un champ de texte arbitraire tandis que app-version doit être un identifiant de version compatible avec semver. built-at est marqué comme une chaîne de date RFC-3339. Vous pouvez obtenir la liste complète des types supportés dans les docs Hadolint.

Hadolint permet l’utilisation de labels qui ne sont pas listés dans votre schéma. Vous pouvez désactiver ceci et restreindre les instructions LABEL à celles présentes dans le schéma en mettant strict-labels : true ou en utilisant l’option –strict-labels.

Formats de sortie

Plusieurs formats de sortie sont supportés par l’option format ou l’indicateur –format. La valeur par défaut est tty qui émet une sortie colorée sur votre terminal. Les couleurs peuvent être désactivées avec l’option –no-color.

Les formateurs alternatifs suivants sont disponibles :

json - Fournit la liste des problèmes détectés sous la forme d'une structure JSON verbeuse, idéale pour une utilisation avec vos propres scripts.
checkstyle - Un rapport compatible avec Checkstyle.
codeclimate - Un rapport compatible avec Code Climate.
gitlab_codeclimate - Variation du rapport Code Climate qui fonctionne avec les fonctionnalités intégrées de qualité du code de GitLab. Cela vous permet d'afficher les erreurs sous forme de widget sur les pages de demande de fusion lorsque vous exécutez Hadolint avec GitLab CI.

Ces formats de sortie sont idéaux pour utiliser Hadolint de manière programmatique ou dans le cadre d’un pipeline CI.

Résumé

Hadolint automatise la détection des problèmes liés aux fichiers Docker. Cela permet à vos images Docker de respecter les meilleures pratiques et les normes organisationnelles. La configuration par défaut est un bon point de départ, mais vous pouvez la personnaliser en fonction de vos besoins en reclassant et en désactivant des règles.

Vous devriez envisager d’intégrer Hadolint à votre outil de CI pour obtenir des rapports instantanés lorsque des modifications de Dockerfile sont validées. Cela accélère la révision du code en donnant aux développeurs une visibilité immédiate des problèmes. Vous pouvez également utiliser l’outil localement pendant que vous travaillez via des extensions d’éditeur prises en charge par la communauté, ce qui permet de raccourcir encore la boucle de rétroaction.