Personnaliser les modules de Caddy avec Nix
Vincent Bernat
Caddy est un serveur web libre écrit en Go. Il gère automatiquement les certificats TLS et propose une syntaxe de configuration simple. Les utilisateurs peuvent étendre ses fonctionnalités via des modules pour ajouter, par exemple, la limitation de débit, la mise en cache et l’intégration à Docker.
Bien que Caddy soit disponible dans Nixpkgs, l’ajout de modules
supplémentaires n’est pas simple1. Le processus de compilation nécessite un accès
Internet, ce que Nix refuse pendant la compilation
pour garantir la reproductibilité. Lorsqu’on essaie de
construire la dérivation suivante en utilisant xcaddy, un outil pour
compiler Caddy avec des modules supplémentaires, cela échoue avec cette erreur :
dial tcp: lookup proxy.golang.org on [::1]:53: connection refused
.
{ pkgs }: pkgs.stdenv.mkDerivation { name = "caddy-with-xcaddy"; nativeBuildInputs = with pkgs; [ go xcaddy cacert ]; unpackPhase = "true"; buildPhase = '' xcaddy build --with github.com/caddy-dns/powerdns@v1.0.1 ''; installPhase = '' mkdir -p $out/bin cp caddy $out/bin ''; }
Les dérivations à sortie fixe (fixed-output derivations) constituent une
exception à cette règle et obtiennent un accès réseau pendant la compilation.
Elles doivent spécifier leur hash de sortie. Par exemple, la fonction fetchurl
produit une dérivation à sortie fixe :
{ stdenv, fetchurl }: stdenv.mkDerivation rec { pname = "hello"; version = "2.12.1"; src = fetchurl { url = "mirror://gnu/hello/hello-${version}.tar.gz"; hash = "sha256-jZkUKv2SV28wsM18tCqNxoCZmLxdYH2Idh9RLibH2yA="; }; }
Pour créer une dérivation à sortie fixe, vous devez définir l’attribut
outputHash
. L’exemple ci-dessous montre comment obtenir le code
source de Caddy, avec certains modules activés, comme une dérivation à sortie
fixe en utilisant xcaddy
et go mod vendor
.
pkgs.stdenvNoCC.mkDerivation rec { pname = "caddy-src-with-xcaddy"; version = "2.8.4"; nativeBuildInputs = with pkgs; [ go xcaddy cacert ]; unpackPhase = "true"; buildPhase = '' export GOCACHE=$TMPDIR/go-cache export GOPATH="$TMPDIR/go" XCADDY_SKIP_BUILD=1 TMPDIR="$PWD" \ xcaddy build v${version} --with github.com/caddy-dns/powerdns@v1.0.1 (cd buildenv* && go mod vendor) ''; installPhase = '' mv buildenv* $out ''; outputHash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc="; outputHashAlgo = "sha256"; outputHashMode = "recursive"; }
Avec une dérivation à sortie fixe, c’est à nous de nous assurer que la sortie est toujours la même :
xcaddy
ne pas compile le programme et conserve le code source2- nous spécifions la version de Caddy que nous voulons construire
- nous spécifions la version de chaque module demandé
Vous pouvez utiliser cette dérivation pour remplacer l’attribut src
dans
pkgs.caddy
:
pkgs.caddy.overrideAttrs (prev: { src = pkgs.stdenvNoCC.mkDerivation { /* ... */ }; vendorHash = null; subPackages = [ "." ]; });
Consultez l’exemple complet dans le dépôt GitHub. Pour une
intégration dans un Flake, vous pouvez utiliser github:vincentbernat/caddy-nix
comme
surcouche à Nixpkgs :
{ inputs = { nixpkgs.url = "nixpkgs"; flake-utils.url = "github:numtide/flake-utils"; caddy.url = "github:vincentbernat/caddy-nix"; }; outputs = { self, nixpkgs, flake-utils, caddy }: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { inherit system; overlays = [ caddy.overlays.default ]; }; in { packages = { default = pkgs.caddy.withPlugins { plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" ]; hash = "sha256-F/jqR4iEsklJFycTjSaW8B/V3iTGqqGOzwYBUXxRKrc="; }; }; }); }
Mise à jour (11.2024)
Cela ne fonctionne pas avec Nixpkgs 24.05 car cette
modification
est nécessaire pour pouvoir changer la valeur de l’attribut vendorHash
.
-
C’est une demande depuis un certain temps. Une solution proposée a été rejetée. Celle décrite dans cet article est un peu différente et je l’ai proposée en remplacement. ↩︎
-
Ce n’est pas parfait : si le code source produit par
xcaddy
change, le hash changerait et la compilation échouerait. ↩︎