单元六 域名与上线 · 第 24 课
HTTPS:正式上线
最后一步:在服务器上安排一个“前台”接收网页请求,配好加密证书,让 https://report.你的域名 正式对外开放。
本课目标
- 理解 HTTPS 的两段加密,以及 Cloudflare 的 SSL 模式。
- 申请 Cloudflare 源站证书,放到服务器上。
- 用 Caddy 做反向代理,开放 80/443 端口,正式上线。
先懂概念:两段路,两段加密
开了橙色云朵以后,一次访问要走两段路:
访问者 ──HTTPS──▶ Cloudflare ──HTTPS──▶ 你的服务器(Caddy)──▶ 周报助手(app:3000)
第一段 第二段- 第一段:访问者到 Cloudflare。证书由 Cloudflare 自动提供,你不用管。
- 第二段:Cloudflare 到你的服务器。需要在服务器上放一张证书。Cloudflare 免费签发一种源站证书(Origin Certificate),有效期可以长达 15 年,专门用于这一段。
Cloudflare 的 SSL 模式决定第二段怎么走,我们用最安全的 Full (strict):第二段也加密,并且严格校验服务器的证书。不要用 Flexible,它的第二段是明文的。
Caddy 是一个网页服务器,在这里充当“前台”:它在 80 和 443 端口接收所有网页请求,用证书完成加密,再把请求转交给后面的周报助手。这种角色叫反向代理。
跟着做
1. 申请源站证书
在 Cloudflare 里进入你的域名:
- 打开 SSL/TLS → Origin Server,点 Create Certificate。
- 私钥类型保持 RSA (2048);主机名保持默认的
*.example.com和example.com;有效期保持 15 年。点 Create。 - 页面显示两段内容:Origin Certificate(证书)和 Private key(私钥)。
私钥只显示这一次。 先别关页面,进行下一步。
2. 把证书放到服务器上
ssh ai-server看到服务器的提示符后,再运行:
mkdir -p ~/apps/weekly-report/certs
cd ~/apps/weekly-report/certs
vim origin.pem按 i,粘贴 Origin Certificate 的全部内容(从 -----BEGIN CERTIFICATE----- 到 -----END CERTIFICATE-----),Esc、:wq 保存。同样地:
vim origin.key粘贴 Private key 的全部内容,保存。然后设置权限:
chmod 600 origin.pem origin.key
ls -l两个文件都是 -rw-------。现在可以关掉 Cloudflare 的证书页面了。
私钥和 API Key 一样重要:不要发给别人,不要放进代码仓库。
3. 写 Caddy 的配置
cd ~/apps/weekly-report
cat > Caddyfile <<'EOF'
report.example.com {
tls /certs/origin.pem /certs/origin.key
reverse_proxy app:3000
}
EOF把 report.example.com 改成你的域名。意思是:收到这个域名的请求,用这两个证书文件加密,然后转交给名叫 app 的服务的 3000 端口。
4. 把 Caddy 加进 compose.yaml
用下面的内容替换整个 compose.yaml,把 你的用户名 换成你的 Docker Hub 用户名,镜像版本和你当前用的保持一致:
cat > compose.yaml <<'EOF'
services:
app:
image: 你的用户名/weekly-report:v2
env_file: .env
restart: unless-stopped
ports:
- "127.0.0.1:3000:3000"
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./certs:/certs:ro
- caddy_data:/data
volumes:
caddy_data:
EOF
docker compose config --quiet && echo 配置正确- 同一个
compose.yaml里的服务可以用名字互相访问,所以 Caddy 能通过app:3000找到周报助手。 volumes把服务器上的Caddyfile和certs文件夹交给 Caddy 容器使用,:ro表示只读。
5. 开放 80 和 443 端口
到云服务商控制台的防火墙页面,添加两条规则:允许 TCP 80 和 TCP 443。
6. 启动
docker compose up -d
docker compose ps
docker compose logs caddyapp 和 caddy 都是 Up,Caddy 的日志里没有 error 字样。
7. 在 Cloudflare 里启用 Full (strict)
- 打开 SSL/TLS → Overview,把加密模式改为 Full (strict)。
- 打开 SSL/TLS → Edge Certificates,开启 Always Use HTTPS,让所有
http://访问自动跳转到https://。
你应该看到
在浏览器访问 https://report.example.com:
- 地址栏有锁形图标;
- 弹出登录框,输入
.env里的用户名和密码; - 周报助手正常工作。
用手机打开同一个网址试试。恭喜,你的网站正式上线了。
排错:Cloudflare 的错误代码
| 错误 | 意思 | 检查 |
|---|---|---|
| 521 | 服务器拒绝连接 | Caddy 有没有运行(docker compose ps) |
| 522 | 连接超时 | 防火墙有没有开放 80/443 |
| 525 | 加密握手失败 | Caddyfile 里的域名是否正确,证书文件内容是否完整 |
| 526 | 源站证书校验失败 | 证书是否过期、是否包含这个域名、Caddy 加载的是不是那两个文件;使用 Cloudflare 源站证书最省事 |
| 重定向次数过多 | 来回跳转 | SSL 模式误设成了 Flexible,改为 Full (strict) |
排查时先看 docker compose logs caddy,再对照上表。
更进一步(可选)
现在任何 IP 都能直接连接你服务器的 80/443 端口。可以在防火墙里把这两个端口的来源限制为 Cloudflare 的 IP 段,让所有访问都必须经过 Cloudflare。IP 段偶尔会变化,需要定期核对。
自检
- 我能解释两段加密,以及为什么用 Full (strict) 而不是 Flexible。
- 证书和私钥在服务器上,权限是
-rw-------。 -
https://report.example.com有锁形图标,需要登录才能使用。 - 我知道 521、522、525、526 分别该查什么。