Nix pour générer des conteneurs pour de l'intégration continue avec plmlab
by Pierre GambarottoIntroduction
Une image docker peut être vue comme une collection d'archive .tar.gz
empilées l'une sur l'autre.
Nix est un gestionnaire de paquetages généraliste, capable de générer n'importe quel format. C'est donc sans surprise que l'on déniche pkgs.dockerTools qui contient de quoi générer des images docker.
Dans ce document, nous allons voir :
- comment générer une image docker avec les binaires de notre choix
- comment utiliser cette image dans une instance docker locale
- comment téléverser l'image dans un repository distant, ici celui de plmlab
- et finalement comment utiliser cette image docker dans un script d'intégration continue.
L'exemple que nous allons développer est celui du générateur statique de site zola
Générer une image
Nous allons construire une image contenant le binaire de zola.
Pour cela, dans le fichier nix/zola-docker.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.dockerTools.buildLayeredImage {
name = "zola-docker";
tag = "latest";
contents = with pkgs; [ #1
bash
coreutils # ls, mkdir, rm …
gnugrep
zola
];
}
#1 : you can add any package from https://search.nixos.org
Pour bâtir l'image, il faut appeler nix-build
, qui par défaut va créer le résultat dans le répertoire ./result
.
nix-build ./nix/zola-docker.nix
# creates ./result, link to
realpath ./result
/nix/store/p5sf2bngqwvr45mq6jb8p6lppzgn5cym-zola.tar.gz
L'image générée fait environ 24Mo.
Utiliser l'image générée dans l'instance docker locale
Comme tout .tar.gz
contenant une image docker, il suffit d'utiliser docker load
.
docker load -i $(realpath ./result)
Vous pouvez vérifier que votre nouvelle image est maintenant présente dans le registry local :
docker image ls | grep zola
zola-docker latest 31b06badba31 53 years ago 70.5MB
Vous pouvez observer que la date de génération de l'image est l'epoch unix.
Test de l'image en local :
# -it : we need a tty
# --rm : remove container after end of exec
# zola-docker : image name to use
# /bin/bash : process to launch
docker run -it --rm zola-docker /bin/bash
## inside the container
bash-5.1# zola -V
zola 0.16.1
bash-5.1# bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
bash-5.1# grep --version
grep (GNU grep) 3.7
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Mike Haertel and others; see
<https://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>.
Téléverser l'image sur le repository de plmlab
Plmlab est une instance de gitlab, qui fournit également la fonctionnalité de dépôt d'images de conteneurs docker (registry).
Pour téléverser une image dans un registry externe à partir de votre dépôt docker local, il faut :
- pouvoir se connecter au dépôt distant :
docker login
- mettre un tag sur l'image avec le nom de l'image sur le dépôt distant
- utiliser
docker push
pour transférer l'image du dépôt local au dépôt distant
Se connecter à un registry externe
Il faut générer un token à partir de votre profil sur plmlab, en lui donnant les droits de lecture et d'écriture.
Définissez ensuite les variables d'environnement suivantes :
# generate a personal token with read and write registrya access
# from https://plmlab.math.cnrs.fr/-/profile/personal_access_tokens
PRIV_REGISTRY_USER=your-plmlab-id ## <= INSERT YOURS !!
PRIV_REGISTRY_PASSWORD="glpat-xyzyxzyxzyxzyxzyxzyxzyzx" ## <= INSERT YOURS !!
PRIV_REGISTRY=registry.plmlab.math.cnrs.fr
Vous pouvez ensuite vous connecter au registry de plmlab :
docker login ${PRIV_REGISTRY} -u ${PRIV_REGISTRY_USER} -p ${PRIV_REGISTRY_PASSWORD}
Cela crée ou complète le fichier ~/.docker/config.json
:
{
"auths": {
"registry.plmlab.math.cnrs.fr": {
"auth": "AbCAbCAbCAbCAbCAbCAbCAbCAbCAbCAbCAbCAbCAbCAbC="
}
}
}
Mettre un tag sur l'image
Il faut ajouter un tag indiquant l'endroit où stocker l'image dans le registry distant.
PRIV_REGISTRY=registry.plmlab.math.cnrs.fr
GITLAB_PROJECT=plmteam/docs/zola-doc
docker tag zola-docker:latest $PRIV_REGISTRY/${GITLAB_PROJECT}/zola-docker
docker login $PRIV_REGISTRY
Vous pouvez observer le nouveau tag sur votre image dans le registry local :
docker image ls | grep zola
zola-docker latest 31b06badba31 53 years ago 66.9MB
registry.plmlab.math.cnrs.fr/plmteam/docs/zola-doc/zola-docker \
latest 31b06badba31 53 years ago 66.9MB
Pousser l'image
# can only push to projet, not group
PRIV_REGISTRY=registry.plmlab.math.cnrs.fr
GITLAB_PROJECT=plmteam/docs/zola-doc
docker push $PRIV_REGISTRY/$GITLAB_PROJECT/zola-docker
Vous pouvez vous rendre sur ${PRIV_REGISTRY}/${GITLAB_PROJECT}/container_registry
pour observer l'apparition de l'image dans l'interface web de gitlab.
On pousse l'image dans la partie container registry
du projet dans lequel on veut l'utiliser pendant l'intégration continue.
Utiliser cette image dans un processus d'intégration continue.
Dans le .gitlab-ci.yml
de votre projet, il faut référéncer l'image du projet courant :
---
image: "${CI_REGISTRY_IMAGE}/zola-docker"
# mandatory : the zola theme is in a submodule
variables:
GIT_SUBMODULE_STRATEGY: recursive
test:
script:
- ./publish private
except:
variables:
- $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
pages:
script:
- ./publish private
artifacts:
paths:
- public
only:
variables:
- $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
environment: production