caddy: add suport for compiling Caddy with plugins#358586
caddy: add suport for compiling Caddy with plugins#358586thiagokokada merged 3 commits intoNixOS:masterfrom
Conversation
pkgs/by-name/ca/caddy/package.nix
Outdated
There was a problem hiding this comment.
Quick question, should we make the build fail if a plugin is provided without the version string?
For example:
pkgs.caddy.withPlugins {
plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" "github.com/caddy-dns/cloudflare" ];
hash = "sha256-AoW35l7QkXunjBzZ43IlyU3UkVXw2D4eyc1jx8xpT0U=";
}After testing this on my darwin machine, I have the following:
$ /nix/store/icp2z20hpf2ps7g4n5rzqdkg5qsjp38z-caddy-2.8.4/bin/caddy build-info
...
dep github.com/caddy-dns/cloudflare v0.0.0-20240703190432-89f16b99c18e
dep github.com/caddy-dns/powerdns v1.0.1
...There was a problem hiding this comment.
Yes, I think I can add an assertion.
There was a problem hiding this comment.
I have added an assertion (using the first non-versioned plugin as an example).
pkgs/by-name/ca/caddy/package.nix
Outdated
There was a problem hiding this comment.
Small nit, imo pluginsHash makes the build log a bit too long, maybe caddy-src-with-plugins is good enough here?
There was a problem hiding this comment.
It's there to ensure a cached build is not used when adding/removing a plugin. This was one of the request in #317881 (comment).
There was a problem hiding this comment.
I have switched to md5 to reduce the length a bit. We could also use a subset of the hash if it's still too long.
There was a problem hiding this comment.
I'm not sure if using md5 is a good idea, IIRC it's considered outdated and insecure (citation needed)?
I took a look into the comment you linked, it seems like it'd be a good idea to include a test to make sure specified plugins are properly installed. I came up with the following but don't have time to dig deeper (feel free to take whatever you need):
diff --git a/pkgs/by-name/ca/caddy/package.nix b/pkgs/by-name/ca/caddy/package.nix
index eea6894ce328..c052da5ef290 100644
--- a/pkgs/by-name/ca/caddy/package.nix
+++ b/pkgs/by-name/ca/caddy/package.nix
@@ -116,6 +116,31 @@ buildGoModule {
outputHash = hash;
outputHashAlgo = "sha256";
};
+
+ doInstallCheck = true;
+ installCheckPhase = ''
+ runHook preInstallCheck
+
+ build_info="$($out/bin/caddy build-info)"
+
+ for plugin in ''${plugins[@]}; do
+ # this won't work :(
+ echo $plugin
+ url=$(echo "$plugin" | cut -d'@' -f1)
+ version=$(echo "$plugin" | cut -d'@' -f2)
+ echo $url
+ echo $version
+
+ if echo "$build_info" | grep -q "$url[[:space:]]*$version"; then
+ echo "$plugin found in build-info"
+ else
+ echo "$plugin not found in build-info" >&2
+ exit 1
+ fi
+ done
+
+ runHook postInstallCheck
+ '';
});
};
For testing:
nom-build --expr 'with import ./. { }; caddy.withPlugins { plugins = [ "github.com/caddy-dns/powerdns@v1.0.1" "github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e" ]; hash = "sha256-AoW35l7QkXunjBzZ43IlyU3UkVXw2D4eyc1jx8xpT0U="; }'There was a problem hiding this comment.
I have added a postInstallCheck as you suggest.
As for the MD5, this is not meant to be secure, just a safety to ensure the user does not forget to update the hash when modifying plugins. A mechanism like this was requested in the original PR.
6068ba7 to
72a4b4b
Compare
72a4b4b to
2144da1
Compare
|
LGTM! Tested with couple more plugins and everything works fine on aarch64-darwin and x86_64-linux |
|
cc @NickCao |
NickCao
left a comment
There was a problem hiding this comment.
Apart from the nitpick, looks pretty good!
pkgs/by-name/ca/caddy/package.nix
Outdated
There was a problem hiding this comment.
| unpackPhase = "true"; | |
| dontUnpack = true; |
2144da1 to
15314ff
Compare
|
fyi theres a typo in the commit message |
e1c0a97 to
56bc3a5
Compare
|
I have also updated the release notes. |
56bc3a5 to
b8a1497
Compare
|
I have added |
pkgs/by-name/ca/caddy/package.nix
Outdated
There was a problem hiding this comment.
I ran into an issue with this check when plugin versions are specified as git-shas.
When given the input:
plugins = [
"github.com/caddy-dns/cloudflare@89f16b99c18ef49c8bb470a82f895bce01cbaece"
"github.com/dulli/caddy-wol@c0d58507c9037191aa9622d531a001db619dd543"
];
hash = "sha256-pKiL3bGcFVcD7r67mY9RtAEHDJc+gq3vz8DkZYssfb4=";
caddy build-info contains:
...
dep github.com/caddy-dns/cloudflare v0.0.0-20240703190432-89f16b99c18e
...
dep github.com/dulli/caddy-wol v1.0.1-0.20240903185854-c0d58507c903
...
This causes this check to fail because the versions were substituted. If I update my input to the versions, it works:
plugins = [
"github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e"
"github.com/dulli/caddy-wol@v1.0.1-0.20240903185854-c0d58507c903"
];
hash = "sha256-pKiL3bGcFVcD7r67mY9RtAEHDJc+gq3vz8DkZYssfb4=";
Do you need to check for the version, or is matching the module sufficient?
There was a problem hiding this comment.
IMO checking module + version is better, and you can get the format it wants beforehand with go get and check the go.mod file
|
Is there intent to support plugins like FrankenPHP? |
pkgs/by-name/ca/caddy/package.nix
Outdated
| let | ||
| pluginsSorted = builtins.sort builtins.lessThan plugins; | ||
| pluginsList = lib.concatMapStrings (plugin: "${plugin}-") pluginsSorted; | ||
| pluginsHash = builtins.hashString "md5" pluginsList; | ||
| pluginsWithoutVersion = builtins.filter (p: !lib.hasInfix "@" p) pluginsSorted; | ||
| in | ||
| assert lib.assertMsg (builtins.length pluginsWithoutVersion == 0) |
There was a problem hiding this comment.
Another non-blocking nit, but in general builtins should be avoided because sometimes we have polyfills for older versions of Nix inside lib, so in general we should always prefer using lib.
There was a problem hiding this comment.
Done, except for builtins.hashString as there does not seem there is an equivalent.
There is no `lib.hashString`, so keep using `builtins` for this one.
08407c0 to
e57d662
Compare
|
It does not work well with a commit-hash version. I'm using https://github.com/mholt/caddy-webdav which does not have a version tag, and it results in an unhelpful build error. caddy.withPlugins {
plugins = [
"github.com/mholt/caddy-webdav@42168ba04c9dc2cd228ab8c453dbab27654e52e6"
];
hash = "";
}Thanks to @kusold 's #358586 (comment), I need to fill in the magic If this is intentional, could we improve the documentation to inform how to generate a valid version string for commit-hash-only plugins? Or if it's possible, could we provide these information directly in build error messages? |
What I usually do is create an empty project and run $ go mod init temp
$ go get github.com/mholt/caddy-webdav
$ grep 'caddy-webdav' go.mod
github.com/mholt/caddy-webdav v0.0.0-20241008162340-42168ba04c9d // indirectI'll make a new PR to update the docs and perhaps a script to automatically generate those strings for untagged plugins |
|
Is it possible to override the caddy source when using I tried |
|
Oof this is a hard one
If you want to apply the patches, try changing the patch paths to To illustrate: $ # im in nixpkgs
$ nix repl -f .
Type :? for help.
Loading installable ''...
Added 23515 variables.
nix-repl> :b (caddy.withPlugins {
plugins = [
"github.com/caddy-dns/cloudflare@v0.0.0-20240703190432-89f16b99c18e"
];
hash = "sha256-JoujVXRXjKUam1Ej3/zKVvF0nX97dUizmISjy3M3Kr8=";
}).src
This derivation produced the following outputs:
out -> /nix/store/48vdfpdaz04wcdqvymx7cx29vsav5pxj-caddy-src-with-plugins-0bbf432f07a600413ee833233180f51d-2.9.0
nix-repl> :b caddy.src
This derivation produced the following outputs:
out -> /nix/store/vwmnpjxxfq1ffc5a82c0q24p0c3sdl3h-source
$ # withPlugins caddy src:
$ > ls -l /nix/store/48vdfpdaz04wcdqvymx7cx29vsav5pxj-caddy-src-with-plugins-0bbf432f07a600413ee833233180f51d-2.9.0/vendor/github.com/caddyserver/caddy/v2
total 608
-r--r--r-- 1 root nixbld 399 Dec 31 1969 AUTHORS
-r--r--r-- 1 root nixbld 11358 Dec 31 1969 LICENSE
-r--r--r-- 1 root nixbld 12002 Dec 31 1969 README.md
-r--r--r-- 1 root nixbld 45621 Dec 31 1969 admin.go
-r--r--r-- 1 root nixbld 33278 Dec 31 1969 caddy.go
...
$ # caddy.src:
$ ls -l /nix/store/vwmnpjxxfq1ffc5a82c0q24p0c3sdl3h-source
total 880
-r--r--r-- 1 root nixbld 399 Dec 31 1969 AUTHORS
-r--r--r-- 1 root nixbld 11358 Dec 31 1969 LICENSE
-r--r--r-- 1 root nixbld 12002 Dec 31 1969 README.md
-r--r--r-- 1 root nixbld 45621 Dec 31 1969 admin.go
-r--r--r-- 1 root nixbld 5790 Dec 31 1969 admin_test.go
-r--r--r-- 1 root nixbld 33278 Dec 31 1969 caddy.go
...Edit: If you want to use a specific version of caddy, you might have to patch xcaddy as well, since the vendored caddy source is pinned in xcaddy's |
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/tailscale-caddy-certificates-not-working/61228/6 |
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/using-nix-to-replace-xcaddy-to-build-caddy-webserver/11765/3 |
|
Please add this to the docs! |
|
How can I replace a caddy module with my own? This is implemented in xcaddy's --with flag |
use this patch for now, should be merged fairly soon #433072 |
|
@stepbrobd´: Thanks a lot for your/this implementation + dedication! |
My immediate thought is using |
|
@stepbrobd Thanks for your fast reply! :)
Yes, think so … Current/simple setup
With both setups |
|
sorry about the late reply, i was at nixcon last week. the problem is with where the above snippet in your reply overrides the withPlugins' build environment variable, where all the dependencies are already fetched by xcaddy (check the with plugins implementation, we are overriding caddy's source with xcaddy's build env) the correct place to do the override is at $ nix build -L --impure --expr '
((import ./. {}).caddy.withPlugins {
plugins = [ "github.com/mholt/caddy-webdav@v0.0.0-20241008162340-42168ba04c9d" ];
hash = "sha256-ymuWQ6ic2MacS3JiGZ5Nu/wq2Iz53TOhxrylRIz3CQc=";
}).overrideAttrs (prev: {
src = prev.src.overrideAttrs (_: { env.GOPROXY = "sup"; });
})
'
...
/nix/store/rgmygksbfyy75iappxpinv0y8lxfq35x-go-1.24.6/bin/go mod init caddy
> go: creating new go.mod: module caddy
> go: to add module requirements and sums:
> go mod tidy
> 2025/09/09 12:00:02 [INFO] Pinning versions
> 2025/09/09 12:00:02 [INFO] exec (timeout=0s): /nix/store/rgmygksbfyy75iappxpinv0y8lxfq35x-go-1.24.6/bin/go get -v github.com/caddyserver/caddy/v2@v2.10.2
> go: github.com/caddyserver/caddy/v2@v2.10.2: invalid proxy URL missing scheme: sup
> 2025/09/09 12:00:02 [FATAL] exit status 1
...shoud give you what you want |
|
for future reference, if you have a question on using caddy withPlugins, or for some reason it doesn't work for your use case, please open a new issue and ping the maintainers there instead of replying to this old PR. thanks! |
This adds a
withPluginsfunction to Caddy package.Fix: #14671
This is an alternative to #317881 and it relies on xcaddy. Looking at #317881 (comment), I am still missing tests. I am unsure if this is a build test (in
checkPhase) or a NixOS test. The remaining requirements should be OK (notably use of xcaddy and FOD).The release notes are missing, I'll add them once this gets a chance to be accepted.
Things done
nix.conf? (See Nix manual)sandbox = relaxedsandbox = truenix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/)Add a 👍 reaction to pull requests you find important.