Caddy 2 泛域名证书/使用社区插件/自定义Docker镜像
脑脑脑
2023年02月08日 21:45

书接上回,如果要使用Caddy 2为多个服务提供反向代理/Web服务器的话,配置文件大概是这样

代码块
CSS
自动换行
复制代码
jellyfin.caddy2tutorial.tk {
	reverse_proxy localhost:8096
}

hass.caddy2tutorial.tk {
	reverse_proxy localhost:8123
}

www.caddy2tutorial.tk {
	root * /part/to/www
    file_server
}
复制成功

如此配置,Caddy 2会为每个域名单独申请一个SSL证书。但是当申请的证书过多时,可能会触发Let's Encrypt的速率限制,所以就需要泛域名证书。

https://caddyserver.com/docs/automatic-https#dns-challenge

查看Caddy 2官方文档,我们发现,Caddy 2自动申请/管理/Renew泛域名证书需要DNS质询才能实现,而官方的Caddy Docker Image是不包括任何DNS质询功能的。好在官方提供了相当方便的方式构建自定义镜像。

https://caddyserver.com/download

上面是官方的Caddy 2二进制文件下载,如果你不是非得用Docker运行Caddy 2的话,那选择需要的插件然后点Download即可。但如果和我一样用着UNRAID,没有systemctl,而且还爱用Docker的话……那就自己build镜像吧。

https://hub.docker.com/_/caddy

通过很简单的Dockerfile,就可以自己构建包含社区插件的Docker镜像了。

代码块
Ruby
自动换行
复制代码
#到 https://hub.docker.com/_/caddy/tags 查找合适的builder镜像tag
#为了更小的体积,我选择builder-alpine
FROM caddy:builder-alpine AS builder

RUN xcaddy build \
#到 https://caddyserver.com/download 寻找所需要的插件添加到此处 记得前面加上--with
#我的域名由Cloudflare提供DNS服务 所以添加caddy-dns/cloudflare插件
#顺手加上其他需要的插件 比如Webdav
    --with github.com/mholt/caddy-webdav \
    --with github.com/caddy-dns/cloudflare

#叠加所需的原始镜像,alpine挺好的
FROM caddy:alpine

COPY --from=builder /usr/bin/caddy /usr/bin/caddy
复制成功

保存为Dockerfile,运行docker build命令

代码块
Ruby
自动换行
复制代码
docker build -t caddy-custom .
# -t 镜像标签 创建容器时需要
# 不要漏掉最后的 . 它代表以当前目录运行命令
复制成功

镜像构建完成,接下来编辑Caddy 2的配置文件Caddyfile

不像文章开头的例子,新的Caddyfile需要达成两个事情

  1. 让Caddy 2使用DNS质询来创建/管理/Renew泛域名证书

  2. 使用泛域名证书

所以新的Caddyfile是这样子的

代码块
Ruby
自动换行
复制代码
caddy2.tutorial *.caddy2.tutorial {
  
# 假设你有caddy2.tutorial这个域名,所有服务都将通过这个域名及它的二级域名提供访问,那么如上
# 一级/二级/三级域名的证书不通用 如果需要为三级域名申请证书 也需要添加在上面
# 泛域名证书好像只支持一个通配符*
  
  tls {
  		DNS cloudflare [token]
  }
  
# 在 tls 这个 block 设定 DNS 质询的相关参数,详情请参考每个社区插件具体的文档
  
  @server-1 host s1.caddy2.tutorial

# 创建一个名为server-1的匹配器 他的匹配规则是请求标头的host字段(即访问的域名)为 s1.caddy2.tutorial 
  
  handle @server-1 {
  		reverse_proxy 10.0.0.10:8123
  }
  
# 处理符合server-1匹配器规则的访问 提供反向代理
  
  @server-2 host s2.caddy2.tutorial
  handle @server-2 {
  		reverse_proxy 10.0.0.10:9090
  }
  
  @static-website host caddy2.tutorial www.caddy2.tutorial
  
# 可以匹配多个条件 比如两个不同的host
  
  handle @static-website {
  		root * /part/to/www
    	file_server
  }
  
  handle {
  		respond 404
  }
# 兜底 处理不匹配所有匹配器的访问 统一返回404错误代码
}
复制成功

完成Caddyfile编辑后,就可以使用自己构建的 带有自定义社区插件的Caddy 2镜像来创建容器了。

代码块
Ruby
自动换行
复制代码
docker run -d --name='custom-caddy' \
--network='host' \
  
# 使用Host网络 将所有端口直接暴露到主机上
# 根据自己的需求 可改为bridge或custom bridge
# 关于Docker Network的知识请寻找其他资料学习

-v '/part/to/caddyv2/data':'/data':'rw' \
  
# -v 参数为挂载,第一个冒号左侧为主机目录 右侧是容器内目录 
# 最后的rw为权限 赋予容器对此目录读(r)写(w)的权限
# 证书文件默认存放在容器内/data目录下

-v '/part/to/caddyconfig/custom-caddy':'/config':'rw' \
  
# 由caddy自动生成的autosave.json默认存放在容器内/config目录下

-v '/part/to/Caddyfile':'/etc/caddy/Caddyfile':'rw' \
  
# 此处挂载的Caddyfle为「文件」而不是「目录」请先编辑好Caddyfile后再挂载

custom-caddy

# 使用我们之前构建的tag为custom-caddy的镜像来创建容器
复制成功

相关文档

https://caddyserver.com/docs/caddyfile/directives/handle#handle

https://caddyserver.com/docs/caddyfile/matchers

https://hub.docker.com/_/caddy