Customize Caddy’s plugins with Nix
Vincent Bernat
4-minute read
Also available in
Filed under
Attachment:
Caddy[1] is an open-source web server written in Go. It handles TLS certificates automatically and comes with a simple configuration syntax. Users can extend its functionality through plugins[2]1 to add features like rate limiting[3], caching[4], and Docker integration[5].
While Caddy is available in Nixpkgs[6], adding extra plugins is
was not simple.2 The compilation process needs Internet
access, which Nix denies during build[7] to ensure reproducibility[8]. When
trying to build the following derivation using xcaddy[9], a tool for building
Caddy with plugins, it fails with this error: 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
'';
}
Fixed-output derivations are an exception to this rule and get network access
during build. They need to specify their output hash. For example, the
fetchurl function produces a fixed-output derivation:
{ stdenv, fetchurl }:
stdenv.mkDerivation rec {
pname = "hello";
version = "2.12.1";
src = fetchurl {
url = "mirror://gnu/hello/hello-${version}.tar.gz";
hash = "sha256-jZkUKv2SV28wsM18tCqNxoCZmLxdYH2Idh9RLibH2yA=";
};
}
To create a fixed-output derivation, you need to set the outputHash
attribute[13]. The example below shows how to output Caddy’s source
code, with some plugin enabled, as a fixed-output derivation using xcaddy and
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";
}
With a fixed-output derivation, it is up to us to ensure the output is always the same:
- we ask
xcaddyto not compile the program and keep the source code,3 - we pin the version of Caddy we want to build, and
- we pin the version of each requested plugin.
You can use this derivation to override the src attribute in pkgs.caddy:
pkgs.caddy.overrideAttrs (prev: {
src = pkgs.stdenvNoCC.mkDerivation { /* ... */ };
vendorHash = null;
subPackages = [ "." ];
});
Check out the complete example in the Git repository[14]. To integrate into a
Flake[15], add github:vincentbernat/caddy-nix as an overlay:
{
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=";
};
};
});
}
Update (2024-11)
This flake won’t work with Nixpkgs 24.05 or older because it relies on this
commit[16]
to properly override the vendorHash attribute.
Update (2025-05)
My pull request[12] for Nixpkgs was merged and since Nixpkgs 25.05, you don’t need to specify the overlay anymore. Check the complete example[17].
- https://caddyserver.com/
- https://caddyserver.com/docs/modules/
- https://github.com/mholt/caddy-ratelimit
- https://github.com/caddyserver/cache-handler
- https://github.com/invzhi/caddy-docker-upstreams
- https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/ca/caddy/package.nix
- https://zero-to-nix.com/concepts/hermeticity/
- https://zero-to-nix.com/concepts/reproducibility/
- https://github.com/caddyserver/xcaddy
- https://github.com/NixOS/nixpkgs/issues/14671
- https://github.com/NixOS/nixpkgs/pull/317881
- https://github.com/NixOS/nixpkgs/pull/358586
- https://nix.dev/manual/nix/2.22/language/advanced-attributes.html#adv-attr-outputHash
- https://github.com/vincentbernat/caddy-nix/blob/main/examples/xcaddy-src/flake.nix
- https://zero-to-nix.com/concepts/flakes/
- https://github.com/nixOS/nixpkgs/commit/eed069a5bc40ba4d871de7700c7eb8d592e98cb6
- https://github.com/vincentbernat/caddy-nix/blob/main/examples/nixpkgs-25.05/flake.nix