Images Nix publics
openEduSuite ne dépend plus des registries amont pour ses images d'infrastructure : chaque image est fournie comme un build Nix reproductible. Chaque image est dérivée de manière déterministe depuis les sources, est reproductible à l'octet près et peut fonctionner entièrement hors ligne, l'exigence de base pour les clusters universitaires isolés.
La famille d'images
Toutes les images suivent le même modèle : un conteneur OCI plat et multi-couches (dockerTools.buildLayeredImage) produit à partir d'un build Nix épinglé du projet amont correspondant. Pas de distribution de base, pas de liste de paquets non maîtrisée ; seulement les binaires et bibliothèques fournis par le store Nix.
| Image | Remplace | Version | Usage |
|---|---|---|---|
dex |
ghcr.io/dexidp/dex |
2.38.0-nix | Fournisseur d'identité OIDC/OAuth2 (SSO ArgoCD) |
helmfile |
ghcr.io/helmfile/helmfile |
1.8.0-nix | Rendu Helmfile pour le sidecar CMP d'ArgoCD |
k8up |
ghcr.io/k8up-io/k8up |
2.13.1-nix | Opérateur de sauvegarde Kubernetes (Restic) |
cloudnative-pg |
ghcr.io/cloudnative-pg/cloudnative-pg |
1.30.1-nix | Opérateur Postgres ; injecte l'instance manager dans chaque pod DB |
postgresql |
ghcr.io/cloudnative-pg/postgresql |
16.15-nix | PostgreSQL 16 compatible CNPG (UID 26, layout /controller, barman-cloud) |
agentflow |
— (successeur de taskfleet) | 0.1.0-nix | Campagnes d'agents de code orchestrées par DAG (af) |
Où les obtenir
Registre public principal (registry.openedusuite.org)
La famille d'images complète et publiquement accessible vit sur la registry OCI publique du projet (Zot derrière Traefik, certificat Let's Encrypt) :
https://registry.openedusuite.org/dex:2.38.0-nix
https://registry.openedusuite.org/helmfile:1.8.0-nix
https://registry.openedusuite.org/k8up:2.13.1-nix
https://registry.openedusuite.org/cloudnative-pg:1.30.1-nix
https://registry.openedusuite.org/postgresql:16.15-nix
https://registry.openedusuite.org/agentflow:0.1.0-nix
Les pulls ne nécessitent aucune authentification ; seuls les pushs sont contrôlés :
$ docker pull registry.openedusuite.org/k8up:2.13.1-nix
GHCR (registre public, prévu)
Les mêmes images seront éventuellement publiées sur ghcr.io/tobias-weiss-ai-xr/… (visibilité & redondance). État : le push GHCR attend un jeton avec le scope Packages: write.
ghcr.io/tobias-weiss-ai-xr/dex:2.38.0-nix
ghcr.io/tobias-weiss-ai-xr/helmfile:1.8.0-nix
ghcr.io/tobias-weiss-ai-xr/k8up:2.13.1-nix
ghcr.io/tobias-weiss-ai-xr/cloudnative-pg:1.30.1-nix
ghcr.io/tobias-weiss-ai-xr/postgresql:16.15-nix
ghcr.io/tobias-weiss-ai-xr/agentflow:0.1.0-nix
Miroir : Zot (interne au cluster)
Les environnements cibles à coupure d'air (air-gap) reflètent la même famille d'images sur un nœud Zot local, qui sert également de cache pull-through (exemple avec une adresse de documentation RFC 5737) :
192.0.2.10:5002/opendesk-nix/<name>:<tag>
Le miroir de registre k3s redirige chaque pull ghcr.io vers Zot ; le cluster reste autonome même en cas de perte de l'accès externe.
Pourquoi Nix ?
- Reproductibilité. Une image est une fonction des entrées du flake Nix. Deux builds de la même révision donnent le même chemin de store et donc le même digest d'image.
- Minimalité par construction. Une image Nix ne contient que ce que le store fournit : le binaire Go amont, les certificats CA,
tzdata. Pas de gestionnaire de paquets, pas de shell superflu. - Opération hors ligne. Les builds peuvent être reconstruits hors ligne depuis une closure nix copy ; le miroir Zot découple le cluster des registres externes.
- Auditabilité. La dérivation est la SBOM : chaque dépendance est lisible dans le chemin de store (
/nix/store/…-k8up-2.13.1).
Construire soi-même
Les dérivations se trouvent dans le dépôt openEduSuite-hrz sous nix/images/infra/ :
$ nix build .#k8up
$ skopeo copy --dest-tls-verify=false --format oci \
docker-archive:result \
docker://ghcr.io/tobias-weiss-ai-xr/k8up:2.13.1-nix
Le flake épingles nixpkgs via flake.lock ; les hachages des modules Go (vendorHash) et des sources sont fixés par dérivation.
Notes sur la compatibilité CNPG
L'image PostgreSQL respecte le contrat de l'opérateur CloudNativePG : UID/GID 26, /controller comme répertoire de travail, /var/run/postgresql comme répertoire socket et barman-cloud pour le chemin de sauvegarde. L'instance manager (comme en amont) n'est pas intégré à l'image ; l'opérateur l'injecte via le conteneur d'init bootstrap-controller. L'image de l'opérateur porte donc le binaire aux deux emplacements (/manager et /controller/instance-manager).
Perspectives
La famille d'images s'agrandit avec les besoins de la suite : les images applicatives (Intercom, fork Stalwart, SOGo) suivront le même chemin Nix. L'objectif reste inchangé : un cluster fonctionnant sans un seul docker pull impératif depuis des registres étrangers.