首页 / 资讯中心 / 文章详情

Caddy 实战:5 分钟给域名开启 HTTPS,自动申请 SSL 证书并反向代理

Caddy 实战:5 分钟给域名开启 HTTPS,自动申请 SSL 证书并反向代理 ★ FEATURED ARTICLE
在服务器部署 Web 服务时我们经常会遇到这样一个需求程序已经运行在服务器的某个端口例如http://127.0.0.1:8080但是对外访问时希望变成https://api.example.com如果使用 Nginx一般还需要配置 Nginx安装 Certbot申请 SSL 证书配置证书路径设置证书自动续期配置 HTTP 跳转 HTTPS而使用Caddy这些工作可以简化很多。Caddy 最大的特点之一就是支持Automatic HTTPS。只要配置中使用了一个有效域名并且 DNS 已经正确指向服务器、80 和 443 端口可以访问Caddy 就可以自动申请并管理 HTTPS 证书。本文就通过一个实际案例演示如何使用 Caddy域名 ↓ https://api.example.com ↓ Caddy ↓ http://127.0.0.1:8080 ↓ Python / Go / Java / Node.js 服务整个过程不需要手动下载 SSL 证书。一、准备环境假设现在有服务器公网 IP203.0.113.10 域名 api.example.com 后端程序 http://127.0.0.1:8080我们的最终目标是https://api.example.com访问这个地址时由 Caddy 转发到http://127.0.0.1:8080服务器这里以 Ubuntu 为例。二、首先配置域名 DNS在域名服务商后台添加一条 A 记录。例如类型A 主机记录 api 记录值 203.0.113.10最终api.example.com解析到203.0.113.10可以通过下面的命令检查pingapi.example.com也可以nslookupapi.example.com例如Name: api.example.com Address: 203.0.113.10说明 DNS 已经基本生效。这里非常重要。如果域名没有正确解析到当前服务器Caddy 就无法正常完成公网 HTTPS 证书的申请。三、检查 80 和 443 端口Caddy 对外主要使用80 HTTP 443 HTTPS因此需要保证服务器防火墙以及云服务器安全组已经放行这两个端口。Caddy 官方 HTTPS 文档同样要求公网 HTTPS 场景下域名正确解析并确保 80、443 可以从外部访问。如果 Ubuntu 开启了 UFW可以执行sudoufw allow80/tcpsudoufw allow443/tcp查看sudoufw status如果使用的是阿里云、腾讯云、AWS、Azure 等云服务器还需要检查云平台的安全组 Firewall Security Group确认TCP 80 TCP 443允许访问。四、安装 CaddyUbuntu / Debian 推荐直接使用官方软件源安装官方安装包同时支持将 Caddy 作为 systemd 服务运行。首先安装依赖sudoaptinstall-ydebian-keyring debian-archive-keyring apt-transport-httpscurl添加 Caddy 官方 GPG Keycurl-1sLfhttps://dl.cloudsmith.io/public/caddy/stable/gpg.key\|sudogpg--dearmor-o/usr/share/keyrings/caddy-stable-archive-keyring.gpg添加软件源curl-1sLfhttps://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt\|sudotee/etc/apt/sources.list.d/caddy-stable.list更新sudoaptupdate安装sudoaptinstallcaddy查看版本caddy version如果能够看到类似v2.x.x说明安装成功。五、查看 Caddy 服务状态安装完成后可以执行systemctl status caddy如果正常应该可以看到Active: active (running)也可以执行sudosystemctlenablecaddy设置开机启动。然后sudosystemctl start caddy六、找到 Caddyfile通过官方 Ubuntu 软件包安装后我们一般直接编辑/etc/caddy/Caddyfile执行sudonano/etc/caddy/Caddyfile也可以使用 vimsudovim/etc/caddy/Caddyfile七、最简单的 HTTPS 配置假设域名为api.example.com最简单的配置甚至可以写成api.example.com { respond Hello HTTPS }保存配置。然后检查配置sudocaddy validate--config/etc/caddy/Caddyfile没有问题后重新加载sudosystemctl reload caddy现在浏览器访问https://api.example.com就应该可以看到Hello HTTPS注意我们整个过程中没有手动申请 SSL 证书。也没有配置ssl_certificate ssl_certificate_key因为这些事情 Caddy 会自动处理。八、Caddy 自动 HTTPS 的原理这是 Caddy 相比传统 Web Server 非常方便的地方。当 Caddyfile 中出现api.example.com { }这样的域名配置后Caddy 会识别这是一个需要 HTTPS 的站点。在满足公网证书申请条件时它会自动完成类似下面的流程读取 Caddyfile ↓ 发现 api.example.com ↓ 检查域名 ↓ 向 CA 申请 TLS 证书 ↓ 安装证书 ↓ 启动 HTTPS ↓ 监听 443 ↓ HTTP 自动跳转 HTTPS而且证书生命周期由 Caddy 自动管理不需要自己写一个定时任务每隔几个月执行 Certbot。Caddy 官方将这套能力称为 Automatic HTTPS包括自动证书管理以及默认的 HTTP → HTTPS 重定向。九、实战反向代理到 8080真实项目一般不会直接让 Caddy 返回文本。例如我们有一个 Python 服务运行127.0.0.1:8080或者localhost:8080我们希望https://api.example.com转发到http://127.0.0.1:8080修改sudonano/etc/caddy/Caddyfile配置api.example.com { reverse_proxy 127.0.0.1:8080 }就这么几行。Caddy 官方提供的 HTTPS reverse proxy 用法也是直接使用域名作为站点地址然后通过reverse_proxy指向后端。检查配置sudocaddy validate--config/etc/caddy/Caddyfile重新加载sudosystemctl reload caddy现在https://api.example.com实际上访问的是http://127.0.0.1:8080十、完整请求流程现在服务器结构就变成浏览器 │ │ HTTPS ▼ https://api.example.com │ │ 443 ▼ Caddy Server │ │ HTTP ▼ 127.0.0.1:8080 │ ▼ 后端程序对于 Python、Go、Node.js 等程序来说可以只监听127.0.0.1例如127.0.0.1:8080而不需要直接暴露8080到公网。公网用户只访问443十一、加入 gzip / zstd 压缩可以继续修改 Caddyfileapi.example.com { encode zstd gzip reverse_proxy 127.0.0.1:8080 }然后sudocaddy validate--config/etc/caddy/Caddyfilesudosystemctl reload caddy对于 Web 页面、JSON、文本接口等可以降低一定的网络传输量。十二、同时配置多个域名Caddy 配置多个网站同样非常方便。例如api.example.com { reverse_proxy 127.0.0.1:8080 } admin.example.com { reverse_proxy 127.0.0.1:9000 } www.example.com { reverse_proxy 127.0.0.1:3000 }对应api.example.com ↓ localhost:8080 admin.example.com ↓ localhost:9000 www.example.com ↓ localhost:3000只需要保证这几个域名的 DNS 都已经指向当前服务器。Caddy 会分别处理相应的 HTTPS 配置。十三、配置 API 服务如果部署的是 FastAPI、Flask、Go API 或 Node.js API例如http://127.0.0.1:8083那么配置只需要api.example.com { reverse_proxy 127.0.0.1:8083 }前端调用https://api.example.com/api/users请求会经过Internet ↓ 443 ↓ Caddy ↓ 127.0.0.1:8083十四、后端使用 Docker 也没问题例如 Dockerdockerrun-d\--namemy-api\-p127.0.0.1:8080:8080\my-api:latest注意这里我特意写成127.0.0.1:8080:8080而不是8080:8080这样 8080 只绑定到本机。公网不能直接http://服务器IP:8080访问。但是 Caddy 可以api.example.com { reverse_proxy 127.0.0.1:8080 }整个结构就是Internet │ │ HTTPS :443 ▼ Caddy │ │ HTTP :8080 ▼ Docker Container这是我比较推荐的一种部署方式。十五、修改 Caddyfile 后不要直接重启每次修改配置后最好先执行sudocaddy validate--config/etc/caddy/Caddyfile确认配置没有问题。然后使用sudosystemctl reload caddy而不是sudosystemctl restart caddyreload可以让 Caddy 加载新的配置同时减少服务中断。正常流程sudonano/etc/caddy/Caddyfile然后sudocaddy validate--config/etc/caddy/Caddyfile最后sudosystemctl reload caddy可以记成修改 ↓ validate ↓ reload十六、查看 Caddy 日志如果 HTTPS 申请失败首先不要反复修改配置。直接看日志sudojournalctl-ucaddy查看最近内容sudojournalctl-ucaddy-n100实时查看sudojournalctl-ucaddy-f这条命令非常有用sudojournalctl-ucaddy-f然后重新加载sudosystemctl reload caddy就能实时看到证书申请 域名验证 配置错误 端口占用 后端连接失败等信息。十七、502 Bad Gateway 怎么解决如果浏览器出现502 Bad Gateway通常说明Caddy 已经正常工作但是 Caddy 无法访问后端。例如配置api.example.com { reverse_proxy 127.0.0.1:8080 }首先在服务器执行curlhttp://127.0.0.1:8080如果这里都失败Connection refused那么不是 Caddy 的问题。而是后端8080根本没有启动。执行ss-lntp|grep8080看看有没有程序监听127.0.0.1:8080十八、HTTPS 证书申请失败怎么办常见原因基本集中在以下几个方面。1. DNS 没生效检查nslookupapi.example.com确认解析出来的是当前服务器 IP。2. 80 端口没有开放检查sudoufw status以及云服务器Security Group3. 443 端口没有开放同样需要检查TCP 4434. Nginx 占用了 80 / 443检查sudoss-lntp|grep:80 以及sudoss-lntp|grep:443 如果看到nginx说明 Nginx 已经占用了端口。如果准备完全使用 Caddy可以先sudosystemctl stop nginx再启动 Caddysudosystemctl restart caddy十九、检查 HTTPS配置完成后可以直接curl-Ihttps://api.example.com或者curl-vhttps://api.example.com如果正常就会看到 TLS 握手以及 HTTP Response。浏览器中打开https://api.example.com地址栏也应该出现 HTTPS 安全标识。二十、只用一条命令也能启动 HTTPS 反向代理如果只是测试并不一定要写 Caddyfile。Caddy 本身提供caddy reverse-proxy\--fromapi.example.com\--tolocalhost:8080这样同样可以快速创建一个 HTTPS reverse proxy。官方命令行文档也说明当--from使用主机名时Caddy 默认会尝试为该地址提供 HTTPS。不过正式生产环境中我还是更建议/etc/caddy/Caddyfile配合systemd运行。方便管理也方便以后增加更多域名。二十一、生产环境推荐配置一个普通 API 项目我一般可以从下面这个配置开始api.example.com { encode zstd gzip reverse_proxy 127.0.0.1:8080 }如果有多个项目api.example.com { encode zstd gzip reverse_proxy 127.0.0.1:8080 } admin.example.com { encode zstd gzip reverse_proxy 127.0.0.1:9000 } app.example.com { encode zstd gzip reverse_proxy 127.0.0.1:3000 }非常直观。二十二、Caddy 和 Nginx 最大的区别对于简单的个人项目、小型 API、Docker 服务来说Caddy 的优势非常明显。Nginx 通常需要考虑域名配置 反向代理 SSL证书 证书路径 Certbot 自动续期 HTTP → HTTPSCaddy 则可以简化为api.example.com { reverse_proxy localhost:8080 }这是 Caddy 最吸引我的地方。它并不是说 Nginx 不好。复杂、高度定制化的 Web 架构中Nginx 依然非常成熟。但是对于个人服务器 独立开发者 Side Project Python API Go API Node.js Docker 服务 内部工具 MCP Server Webhook这种场景Caddy 的配置体验确实非常舒服。二十三、最终部署结构完成之后我们的服务器架构实际上非常简单Internet │ │ api.example.com │ │ HTTPS :443 ▼ ┌───────────┐ │ Caddy │ └─────┬─────┘ │ │ HTTP │ 127.0.0.1:8080 │ ▼ ┌───────────────┐ │ Backend API │ │ Python / Go │ │ Node / Java │ └───────────────┘公网只需要开放80 443业务端口8080 9000 3000则可以只监听127.0.0.1不直接暴露到公网。二十四、常用命令汇总最后把 Caddy 常用命令整理一下。查看版本caddy version查看运行状态systemctl status caddy启动sudosystemctl start caddy停止sudosystemctl stop caddy重启sudosystemctl restart caddy平滑重新加载配置sudosystemctl reload caddy检查 Caddyfilesudocaddy validate--config/etc/caddy/Caddyfile格式化 Caddyfilesudocaddyfmt--overwrite/etc/caddy/Caddyfile查看日志sudojournalctl-ucaddy实时查看日志sudojournalctl-ucaddy-f总结如果只是想给一个运行在服务器上的 Web 服务快速增加 HTTPSCaddy 确实非常适合。整个流程可以总结成1. 域名解析到服务器 IP ↓ 2. 开放 80 / 443 ↓ 3. 安装 Caddy ↓ 4. 编辑 /etc/caddy/Caddyfile ↓ 5. 配置 reverse_proxy ↓ 6. Caddy 自动申请 HTTPS 证书 ↓ 7. https://域名 直接访问最终真正核心的配置可能只有api.example.com { reverse_proxy 127.0.0.1:8080 }几行配置就完成了域名绑定 HTTPS SSL 证书申请 证书管理 HTTP → HTTPS 反向代理如果经常在 Ubuntu 服务器上部署各种 Python、Go、Node.js、Docker API 服务Caddy 是一个非常值得掌握的工具。
阅读完成 · 觉得有帮助?
咨询建站