跳转到内容

反向代理容器 ​

家庭实验室里服务一多,每个都记一个 http://<ip>:<端口> 很快就记不住。反向代理(reverse proxy)用一个入口,按域名或路径把请求转发到后面各个服务,顺带能统一签发 HTTPS 证书。

这是容器最划算的场景之一:反向代理本身很轻,常驻运行,换一台机器不用重新想怎么部署。本文用开源的 Caddy 作为示例——它的最大特点是默认自动申请和续期 HTTPS 证书,配置文件也是本站见过的同类工具里最短的。

适合谁 ​

你的情况合不合适
只想用域名代替内网 IP+端口,且都在内网访问合适,用 Caddy + 内网 DNS 就够,不需要对外暴露
想把某个服务放到公网访问可以做,但要认真读完下面的暴露风险
想要图形界面而不是写配置文件可以选 Nginx Proxy Manager 这类带 Web UI 的方案,通常跑在 Docker 里;本站不建议在 LXC 里叠 Docker(见容器分类导读),可以换成跑 Docker 的虚拟机
后端服务本身已经有自己的 HTTPS 和认证反向代理只是多一层入口,收益有限,视情况决定要不要加

资源规划 ​

项建议说明
形态非特权 LXC 容器,Debian/Ubuntu 模板见创建第一个容器
vCPU1转发请求本身几乎不耗 CPU
内存512 MB–1 GBCaddy 本身很省内存
磁盘4–8 GB只放程序、配置和证书缓存
网络固定内网 IP反向代理是别人访问服务的入口,IP 漂移会导致所有转发规则失效,见静态 IP 配置

安装 Caddy ​

按创建第一个容器建好一台 Debian 容器,在容器内部按 Caddy 官方文档添加官方仓库并安装:

sh
# 在容器内部执行(Debian/Ubuntu)
apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
  | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
  | tee /etc/apt/sources.list.d/caddy-stable.list
apt update
apt install -y caddy

安装包会自动创建并启动 caddy 这个 systemd 服务,配置文件在 /etc/caddy/Caddyfile。

具体命令以官方文档为准

包管理器仓库地址、GPG 密钥指纹这类细节 Caddy 官方可能会调整,装之前对照 Caddy 官方安装文档确认没有变化。

配置反向代理规则 ​

Caddy 的配置文件语法很直白。编辑 /etc/caddy/Caddyfile(先备份原文件):

sh
# 在容器内部执行,改配置前先备份
cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak

一个最小示例,把 jellyfin.home.example 转发到局域网里另一台机器的 Jellyfin:

text
jellyfin.home.example {
    reverse_proxy 192.168.1.50:8096
}

改完让配置生效:

sh
# 在容器内部执行
systemctl reload caddy

只在内网用,先解决域名解析

上面的域名要能被内网设备解析到反向代理容器的 IP,才能生效。最简单的方式是在内网 DNS(AdGuard Home、Pi-hole 或路由器的 DNS 覆盖)里加一条记录,把 jellyfin.home.example 指向这台容器的 IP。这种情况下 Caddy 默认还是会尝试用公网的 Let's Encrypt 签证书,域名解析不到公网会失败;纯内网场景可以配置 Caddy 使用内部 CA 或自签证书,具体做法参考 Caddy 官方文档。

把服务暴露到公网 ​

如果确实要把某个服务开放给公网访问(比如自己在外面能连回家里的某个应用),Caddy 能在域名指向这台容器公网地址、且 80/443 端口能从公网访问到时自动签发 Let's Encrypt 证书。

把反向代理暴露到公网,等于把它背后的服务暴露到公网

这台容器一旦能从公网访问,它转发到的每一个后端服务也间接暴露了。开始之前确认:

  1. 只转发你真的要对外开放的服务,管理面板、NAS 界面、PVE 自己的 Web UI 这类不应该直接暴露的服务,不要写进公网可达的转发规则里。
  2. 后端服务自己有登录认证,反向代理不会替你加认证——它只是转发流量。需要额外一层认证时,用 Caddy 的 basicauth 指令或者上游服务自带的账号体系,更完整的方案见安全地远程访问(WireGuard/Tailscale 等,通常比直接开放公网端口更安全)。
  3. 路由器上的端口转发范围要精确,只转发 80/443 到这台容器,不要图省事把整个网段暴露。
  4. 回退方式:出问题时,先在路由器上撤销 80/443 的端口转发,服务立刻恢复为仅内网可访问;再排查 Caddy 或后端服务的问题。

对个人/家庭场景,更推荐用 Tailscale 容器这类基于私有网络的远程访问方式,而不是把服务直接暴露到公网。

检查结果 ​

  1. 在局域网内用配置好的域名访问,能看到后端服务的正常页面,而不是 Caddy 自己的默认页。
  2. systemctl status caddy 状态是 active (running),没有报错。
  3. 如果启用了公网 HTTPS,用浏览器访问对应域名,证书应显示由 Let's Encrypt(或你配置的 CA)签发,地址栏没有证书警告。
  4. 换一台没有加过内网 DNS 记录的设备,直接用域名访问应该失败(说明解析确实只在你配置的范围内生效,而不是意外能被公网解析到)。
  5. 重启容器(pct reboot <ctid>),确认 Caddy 自动拉起,反向代理规则依然生效。

常见问题 ​

证书签发失败。 先确认域名的公网解析确实指向这台容器所在的公网地址,且路由器的 80/443 端口转发已经生效(外部能连通才能完成 ACME 验证)。纯内网场景下公网证书本来就签不下来,见上文的内网证书方案。

能内网访问,改成公网就打不开。 检查路由器端口转发规则、以及容器自身或 PVE 防火墙有没有挡住 80/443。

转发生效但后端服务报错(比如提示协议不对)。 一些应用需要知道自己是被反向代理转发的(X-Forwarded-* 请求头),Caddy 默认会带上这些头,检查后端应用的反向代理相关设置是否开启。

想换成图形界面的方案。 可以考虑 Nginx Proxy Manager,但它官方发行形态基于 Docker,本站不建议在 LXC 容器里叠加 Docker(见容器分类导读),更合适的做法是单独开一台跑 Docker 的虚拟机。

参考资料 ​

Proxmox VE 非官方中文使用指南,与 Proxmox Server Solutions GmbH 无隶属关系。