Skip to main content

Get extra plugins for Caddy Server with xcaddy

·488 words·3 mins·
Table of Contents

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
#


  1. 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.mod to switch from remote to local dependencies, and to always be specific in the versioning of dependent as well as one’s own packages. ↩︎

Danai Sae-Han
Author
Danai Sae-Han
For the past 17 years, Danai has worked for over 50 clients of different sizes, cultures and locations to implement and integrate different software stacks from Ray.io, PyTorch, Grails, OpenText and SAP. You can reach out via the Contact page or through some of the social links.