The default Caddy Server on Debian is well maintained, but it is a plain
vanilla version. For any extra plugins, i.e. modules, you will need to rebuild Caddy.
This article will show you how to build and use xcaddy to easily build Caddy
and add as many plugins as you want, all the while retaining the Debian
package and its systemd integration.
Build requirements #
We must install a few packages to get going. I assume a Debian/testing environment at the moment of writing this article and a working internet connection1 on your build system.
apt install golang git caddy
Build xcaddy #
xcaddy is a tool that allows you to compile custom caddy binaries with extra
plugins (our use case here), and it aids plugin developers. We will fetch the
latest source code hosted on GitHub directly from within the go compiler.
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
One can also consider
installing xcaddy through Cloudsmith.
I prefer building xcaddy myself from scratch, but that is just a personal
sentiment.
Build our own Caddy with extra plugins #
We can now use xcaddy and add as many plugins as we want during build-time
using the --with parameter and the plugin’s upstream GitHub address.
For instance, if you prefer to have your logs in the more traditional Apache-like
Common Log Format instead of JSON, you can use the
transform-encoder plugin.
go/bin/xcaddy build --with github.com/caddyserver/transform-encoder
You can now test and run the newly built Caddy with:
./caddy --help
Integration of custom Caddy within Debian #
Once you are satisfied with your custom Caddy, let’s make it available
system-wide and integrate with the Debian’s default caddy package.
We first override Debian’s standard /usr/bin/caddy and move it to
/usr/bin/caddy.default by “diverting” it, then we move our own Caddy
as /usr/bin/caddy.custom, we let Debian know that we have
basically two Caddy versions and we set up the priority of each
alternative (our custom Caddy version must have the highest priority).
Finally we restart the service.
1sudo dpkg-divert --divert /usr/bin/caddy.default --rename /usr/bin/caddy
2sudo mv ./caddy /usr/bin/caddy.custom
3sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.default 10
4sudo update-alternatives --install /usr/bin/caddy caddy /usr/bin/caddy.custom 50
5sudo systemctl restart caddy
Reverting when things go bad #
If you want to switch back to Debian’s default Caddy version, simply change the alternative and restart the service:
1sudo update-alternatives --config caddy
2sudo systemctl restart caddy
Upgrading Caddy #
To upgrade Caddy after this point, you may run caddy upgrade.
This attempts to download a build with the same plugins as your
current build, with the latest version of Caddy, then replace
the current binary with the new one.
Sources #
-
For secure, air-gapped systems, one can consider several things such as a separate source control server with local forks, a thorough review of every new pull refresh, modification of
go.modto switch from remote to local dependencies, and to always be specific in the versioning of dependent as well as one’s own packages. ↩︎