This command line tool and associated Go package makes it easy to make custom builds of the Caddy Web Server.
It is used heavily by Caddy plugin developers as well as anyone who wishes to make custom caddy
binaries (with or without plugins).
Stay updated, be aware of changes, and please submit feedback! Thanks!
You can download binaries that are already compiled for your platform from the Release tab.
You may also build xcaddy
from source:
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
For Debian, Ubuntu, and Raspbian, an xcaddy
package is available from our Cloudsmith repo:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list
sudo apt update
sudo apt install xcaddy
If you find yourself fighting xcaddy in relation to your custom or proprietary build or development process, it might be easier to just build Caddy manually!
Caddy's main.go file, the main entry point to the application, has instructions in the comments explaining how to build Caddy essentially the same way xcaddy does it. But when you use the go
command directly, you have more control over the whole thing and it may save you a lot of trouble.
The manual build procedure is very easy: just copy the main.go into a new folder, initialize a Go module, plug in your plugins (add an import
for each one) and then run go build
. Of course, you may wish to customize the go.mod file to your liking (specific dependency versions, replacements, etc).
The xcaddy
command has two primary uses:
- Compile custom
caddy
binaries - A replacement for
go run
while developing Caddy plugins
The xcaddy
command will use the latest version of Caddy by default. You can customize this for all invocations by setting the CADDY_VERSION
environment variable.
As usual with go
command, the xcaddy
command will pass the GOOS
, GOARCH
, and GOARM
environment variables through for cross-compilation.
Note that xcaddy
will ignore the vendor/
folder with -mod=readonly
.
Syntax:
$ xcaddy build [<caddy_version>]
[--output <file>]
[--with <module[@version][=replacement]>...]
[--replace <module[@version]=replacement>...]
[--embed <[alias]:path/to/dir>...]
-
<caddy_version>
is the core Caddy version to build; defaults toCADDY_VERSION
env variable or latest.
This can be the keywordlatest
, which will use the latest stable tag, or any git ref such as:- A tag like
v2.0.1
- A branch like
master
- A commit like
a58f240d3ecbb59285303746406cab50217f8d24
- A tag like
-
--output
changes the output file. -
--with
can be used multiple times to add plugins by specifying the Go module name and optionally its version, similar togo get
. Module name is required, but specific version and/or local replacement are optional. -
--replace
is like--with
, but does not add a blank import to the code; it only writes a replace directive togo.mod
, which is useful when developing on Caddy's dependencies (ones that are not Caddy modules). Try this if you got an error when using--with
, likecannot find module providing package
. -
--embed
can be used multiple times to embed directories into the built Caddy executable. The directory can be prefixed with a custom alias and a colon:
to use it with theroot
directive and sub-directive.
$ xcaddy build \
--with github.com/caddyserver/ntlm-transport
$ xcaddy build v2.0.1 \
--with github.com/caddyserver/ntlm-transport@v0.1.1
$ xcaddy build master \
--with github.com/caddyserver/ntlm-transport
$ xcaddy build a58f240d3ecbb59285303746406cab50217f8d24 \
--with github.com/caddyserver/ntlm-transport
$ xcaddy build \
--with github.com/caddyserver/ntlm-transport=../../my-fork
$ xcaddy build \
--with github.com/caddyserver/ntlm-transport@v0.1.1=../../my-fork
You can even replace Caddy core using the --with
flag:
$ xcaddy build \
--with github.com/caddyserver/caddy/v2=../../my-caddy-fork
$ xcaddy build \
--with github.com/caddyserver/caddy/v2=github.com/my-user/caddy/v2@some-branch
This allows you to hack on Caddy core (and optionally plug in extra modules at the same time!) with relative ease.
You may embed directories into the Caddy executable:
$ xcaddy build --embed foo:./sites/foo --embed bar:./sites/bar
$ cat Caddyfile
foo.localhost {
root * /foo
file_server {
fs embedded
}
}
bar.localhost {
root * /bar
file_server {
fs embedded
}
}
This allows you to serve 2 sites from 2 different embedded directories, which are referenced by aliases, from a single Caddy executable.
If you need to work on Caddy's dependencies, you can use the --replace
flag to replace it with a local copy of that dependency (or your fork on github etc if you need):
$ xcaddy build some-branch-on-caddy \
--replace golang.org/x/net=../net
If you run xcaddy
from within the folder of the Caddy plugin you're working on without the build
subcommand, it will build Caddy with your current module and run it, as if you manually plugged it in and invoked go run
.
The binary will be built and run from the current directory, then cleaned up.
The current working directory must be inside an initialized Go module.
Syntax:
$ xcaddy <args...>
<args...>
are passed through to thecaddy
command.
For example:
$ xcaddy list-modules
$ xcaddy run
$ xcaddy run --config caddy.json
The race detector can be enabled by setting XCADDY_RACE_DETECTOR=1
. The DWARF debug info can be enabled by setting XCADDY_DEBUG=1
.
$ xcaddy version
builder := xcaddy.Builder{
CaddyVersion: "v2.0.0",
Plugins: []xcaddy.Dependency{
{
ModulePath: "github.com/caddyserver/ntlm-transport",
Version: "v0.1.1",
},
},
}
err := builder.Build(context.Background(), "./caddy")
Versions can be anything compatible with go get
.
Because the subcommands and flags are constrained to benefit rapid plugin prototyping, xcaddy does read some environment variables to take cues for its behavior and/or configuration when there is no room for flags.
CADDY_VERSION
sets the version of Caddy to build.XCADDY_RACE_DETECTOR=1
enables the Go race detector in the build.XCADDY_DEBUG=1
enables the DWARF debug information in the build.XCADDY_SETCAP=1
will runsudo setcap cap_net_bind_service=+ep
on the resulting binary. By default, thesudo
command will be used if it is found; setXCADDY_SUDO=0
to avoid usingsudo
if necessary.XCADDY_SKIP_BUILD=1
causes xcaddy to not compile the program, it is used in conjunction with build tools such as GoReleaser. ImpliesXCADDY_SKIP_CLEANUP=1
.XCADDY_SKIP_CLEANUP=1
causes xcaddy to leave build artifacts on disk after exiting.XCADDY_WHICH_GO
sets the go command to use when for example more then 1 version of go is installed.XCADDY_GO_BUILD_FLAGS
overrides default build arguments. Supports Unix-style shell quoting, for example: XCADDY_GO_BUILD_FLAGS="-ldflags '-w -s'". The provided flags are applied togo
commands: build, clean, get, install, list, run, and testXCADDY_GO_MOD_FLAGS
overrides defaultgo mod
arguments. Supports Unix-style shell quoting.
© 2020 Matthew Holt