使用 xcaddy 构建自定义 Caddy 服务器

简介

xcaddy​ 是一个命令行工具和关联的 Go 包,使用户能够轻松地构建自定义版本的 Caddy Web Server。这个工具不仅被 Caddy 插件开发者广泛使用,还适用于任何希望创建带有或不带插件的自定义 caddy​ 二进制文件的用户。无论你是在开发新插件,还是想要定制 Caddy 的功能,xcaddy​ 都提供了一个灵活而强大的解决方案。

环境要求

在使用 xcaddy​ 之前,首先需要确保你的系统中已安装 Go。这可以通过访问 Go 的官方网站并按照其安装说明进行操作。

安装方式

用户可以选择从 Release 标签下载已经编译好的二进制文件,或从源代码构建 xcaddy​。如果选择从源代码构建,可以使用以下命令:

go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest

对于 Debian、Ubuntu 和 Raspbian 用户,可以通过 Caddy 的 Cloudsmith 仓库安装 xcaddy​:

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

高级提示

在使用 xcaddy​ 进行自定义构建时,可能会遇到一些复杂情况。对此,建议用户直接手动构建 Caddy。Caddy 的 main.go 文件 中提供了如何手动构建的详细说明。通过直接使用 go​ 命令,用户可以掌控整个构建过程,从而避免一些潜在问题。

手动构建的过程也非常简单:只需将 main.go​ 复制到新文件夹中,初始化一个 Go 模块,添加所需插件(对每个插件进行 import​),然后运行 go build​。当然,用户也可以根据个人需求自定义 go.mod​ 文件(例如,特定的依赖版本、替换等)。

命令用法

xcaddy​ 命令主要有两个用途:

  1. 编译自定义的 caddy​ 二进制文件。
  2. 在开发 Caddy 插件时替代 go run​。

默认情况下,xcaddy​ 会使用最新版本的 Caddy。用户也可以通过设置 CADDY_VERSION​ 环境变量来定制所有调用的版本。在使用 go​ 命令时,xcaddy​ 会将 GOOS​、GOARCH​ 和 GOARM​ 环境变量传递给编译过程,以便进行交叉编译。

值得注意的是,xcaddy​ 在使用 -mod=readonly​ 时会忽略 vendor/​ 文件夹。

自定义构建

使用 xcaddy​ 构建的基本语法如下:

$ xcaddy build [<caddy_version>]
    [--output <file>]
    [--with <module[@version][=replacement]>...]
    [--replace <module[@version]=replacement>...]
    [--embed <[alias]:path/to/dir>...]

其中:

  • <caddy_version>​ 是要构建的 Caddy 核心版本;默认使用 CADDY_VERSION​ 环境变量或最新版本。可以使用 latest​ 关键字获取最新的稳定标签,也可以是任何 git 引用,例如:

    • 标签如 v2.0.1
    • 分支如 master
    • 提交如 a58f240d3ecbb59285303746406cab50217f8d24
  • --output​ 参数可以更改输出文件的名称。

  • --with​ 参数可以多次使用,以添加插件,格式与 go get​ 类似。模块名是必需的,但特定版本和/或本地替换是可选的。

  • --replace​ 参数类似于 --with​,但不会向代码中添加空的导入;它只写入一个替换指令到 go.mod​ 文件中,这在开发 Caddy 的依赖项时非常有用。

  • --embed​ 可以多次使用,将目录嵌入到构建的 Caddy 可执行文件中。目录可以带有自定义别名,以便在 root​ 指令和子指令中使用。

示例

以下是一些使用 xcaddy​ 的示例:

$ 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

此外,用户甚至可以使用 --with​ 标志替换 Caddy 核心:

$ 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

这样的灵活性使得在进行 Caddy 核心开发时,能够方便地同时插入额外的模块。

嵌入目录

用户还可以将目录嵌入到 Caddy 可执行文件中:

$ 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
	}
}

以上示例展示了如何从单个 Caddy 可执行文件中为两个不同的嵌入目录提供服务,这些目录通过别名进行引用。

插件开发

如果用户在 Caddy 插件的工作目录中运行 xcaddy​(不带 build​ 子命令),则会使用当前模块构建 Caddy 并运行,就像手动插入并调用 go run​ 一样。编译的二进制文件将在当前目录中构建并运行,然后进行清理。

当前工作目录必须在已初始化的 Go 模块内。其语法如下:

$ xcaddy <args...>
  • <args...>​ 参数将传递给 caddy​ 命令。

例如:

$ xcaddy list-modules
$ xcaddy run
$ xcaddy run --config caddy.json

用户还可以通过设置 XCADDY_RACE_DETECTOR=1​ 启用竞争检测器,通过设置 XCADDY_DEBUG=1​ 来启用 DWARF 调试信息。

获取 xcaddy​ 的版本

想要查看 xcaddy​ 的版本,可以使用以下命令:

$ xcaddy version

库用法

用户在使用 xcaddy​ 作为库时,可以按照以下代码进行:

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")

版本可以是任何与 go get​ 兼容的版本。

环境变量

由于子命令和标志的约束,xcaddy​ 会读取一些环境变量,以便在没有可用标志的情况下调整其行为或配置。这些环境变量包括:

  • CADDY_VERSION​:设置要构建的 Caddy 版本。
  • XCADDY_RACE_DETECTOR=1​:在构建中启用 Go 竞争检测器。
  • XCADDY_DEBUG=1​:在构建中启用 DWARF 调试信息。
  • XCADDY_SETCAP=1​:在生成的二进制文件上运行 sudo setcap cap_net_bind_service=+ep​。如果找到了 sudo​,将默认使用该命令;要避免使用 sudo​,可以设置 XCADDY_SUDO=0​。
  • XCADDY_SKIP_BUILD=1​:使 xcaddy​ 不编译程序,此选项与 GoReleaser 等构建工具一起使用时特别有用。
  • XCADDY_SKIP_CLEANUP=1​:使 xcaddy​ 在退出后保留构建工件。
  • XCADDY_WHICH_GO​:设置在安装了多个 Go 版本时使用的 Go 命令。
  • XCADDY_GO_BUILD_FLAGS​:覆盖默认的构建参数,支持 Unix 风格的 shell 引号。
  • XCADDY_GO_MOD_FLAGS​:覆盖默认的 go mod​ 参数。

结语

xcaddy​ 是一个强大的工具,适合需要定制化的 Caddy 用户和开发者。通过灵活的构建选项和强大的插件支持,用户可以根据自己的需求构建出最适合的 Caddy 版本。在使用过程中,如有任何问题,欢迎用户提供反馈和建议。


参考文献

  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    12 引用 • 54 回帖 • 163 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...