Et si on créait un « Dockerfile-lock » ?
En janvier 2019, avec mon meilleur anglais, je m'étais questionné sur la possibilité d'ajouter un système de verrouillage de version à Docker, similaire à celui de Node.js/NPM.
L'idée était de :
- pouvoir utiliser librement les tags pour désigner les images Docker et bénéficier des avantages liés (mises à jour notamment) dans les environnements de développement ;
- figer la version des images lorsqu'elles sont utilisées dans les environnements de recette et de production.
Qu'est-ce que le package-lock.json
de Node.js/NPM ?
Concrètement, Node.js/NPM propose un fichier package.json
qui contient les dépendances d'un projet, ainsi que leurs versions :
Fichier : package.json (json)1{ 2 "dependencies": { 3 "xxx": "^1.2.3", 4 "yyy": "~2.2.2", 5 "zzz": "3.1.4" 6 } 7}
Mais les versions des dépendances ne sont pas forcément figées :
^1.2.3
permet d'installer toutes les versions1.X.Y
;~2.2.2
autorise les versions2.2.X
.
Ainsi, lorsque l'on réinstalle les dépendances sur une autre machine, les versions peuvent avoir évolué entre-temps. Cela peut être très pratique... ou à l'inverse casser le projet.
C'est pour cela que lors de l'installation des dépendances, npm génère également un fichier package-lock.json
qui contient les versions exactes des dépendances.
Ce fichier est ensuite utilisé lors de l'installation des dépendances dans les environnements de recette et de production, via la commande npm ci
.
Une première méthode artisanale
À l’époque, j'avais réalisé deux scripts pour proposer une solution temporaire. Je déconseille fortement de les utiliser en l'état. Ils ne couvrent que trop peu de cas.
Docker-build.sh
Ce script devait être utilisé à la place docker build
et génère un fichier lock :
Fichier : docker-build.sh (bash)1#!/bin/bash 2 3docker build "$@" 4 5dockerfile="Dockerfile" 6while test $# -gt 0; do 7 case "$1" in 8 -f|--file) 9 shift 10 dockerfile=$1 11 shift 12 ;; 13 -f=*) 14 dockerfile=${1#"-f="} 15 shift 16 ;; 17 --file=*) 18 dockerfile=${1#"--file="} 19 shift 20 ;; 21 *) 22 shift 23 ;; 24 esac 25done 26lockfile="$dockerfile-lock" 27 28echo "Make $lockfile from $dockerfile" 29 30cp $dockerfile $lockfile 31grep ^FROM $lockfile | while read -r line ; do 32 33 image=`echo $line | cut -d" " -f2` 34 digest=`docker inspect --format='{{index .RepoDigests 0}}' $image` 35 36 echo "$image > $digest" 37 38 sed -i -e "s/$image/$digest/g" $lockfile 39done
Docker-ci.sh
Ce script permet de construire une image à partir du fichier lock. Étant donné que docker build --file Dockerfile-lock .
fait la même chose, je vous en épargne le contenu.
Et aujourd'hui ?
Michael Perel avait répondu à mon post sur le forum Docker et a conçu un outil nommé Docker-lock qui améliore le concept. Il fonctionne avec les fichiers Dockerfile
mais également les fichiers docker-compose.yml
par exemple.
― Valentin LORTET