Et si on créait un « Dockerfile-lock » ?

Il y a quelques années, je m'étais questionné sur la possibilité de créer un système de verrouillage de version pour Docker similaire à Node.js/NPM. Voici ce que cela a donné.

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 versions 1.X.Y ;
  • ~2.2.2 autorise les versions 2.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

Cet article vous a plu ? N'hésitez pas à le partager :

Découvrir d'autres articles