SERVER_NAME=your-domain.com:8443无效,因Caddy只将SERVER_NAME解析为主机名,不支持端口;正确做法是用自定义Caddyfile显式配置https_port 8443、监听:8443并手动指定TLS证书路径。

FrankenPHP 容器不能通过 SERVER_NAME 设置非默认 HTTPS 端口(比如 :8443),因为 Caddy 不接受带端口的域名格式;必须改用显式监听 + 手动 TLS 配置方式。
为什么 SERVER_NAME=your-domain.com:8443 无效
Caddy 的 SERVER_NAME 环境变量只用于解析“主机名”,不是 URL。写成 your-domain.com:8443 或 localhost:8443 会被直接忽略,Caddy fallback 到默认行为(监听 :80 和 :443,并尝试自动 HTTPS)。这不是 FrankenPHP 的 bug,而是 Caddy 的设计约束。
正确做法:用自定义 Caddyfile 显式监听 + 指定证书路径
要跑在 :8443 上的 HTTPS,你得绕过 SERVER_NAME 自动逻辑,手写 Caddy 配置:
- 在项目根目录放一个
Caddyfile,内容类似:
{
https_port 8443
}
:8443 {
tls /app/certs/tls.crt /app/certs/tls.key
frankenphp {
num_threads auto
}
php_server
}
关键点:
立即学习“PHP免费学习笔记(深入)”;
-
https_port 8443告诉 Caddy 把 HTTPS 监听地址从默认:443改成:8443 -
:8443 { ... }是监听块,不是域名,不触发 ACME -
tls指令必须提供证书路径,不能省略——Caddy 不会为你自签非:443端口的证书 - 容器启动时需挂载证书文件:
-v $(pwd)/certs:/app/certs
Docker 启动命令要同步暴露端口
光配 Caddyfile 不够,宿主机端口也得对齐:
- 如果想从外部用
https://example.com:8443访问,Docker 必须映射-p 8443:8443 - 不要写
-p 8443:443——这会让 Caddy 在容器内监听:443,但请求被转发到:443,实际还是走默认 HTTPS 流程 - 若同时保留
:443和:8443,Caddyfile 里要写两个监听块,且证书路径不能冲突
本地开发快速生成测试证书
没现成证书?可以用 mkcert 本地签发(仅限开发):
- 运行
mkcert -install(一次) - 再运行
mkcert localhost 127.0.0.1 ::1,生成localhost+2-key.pem和localhost+2.pem - 把这两个文件挂进容器,
tls指令里路径对应上即可 - 浏览器首次访问会提示不安全,点“高级→继续访问”即可(因是私有 CA)
真正容易被忽略的是:Caddy 对非标准端口的 HTTPS 完全不自动管理证书,automatic_https 特性只作用于 :443 和 :80 组合。一旦换端口,证书生命周期、重定向、HTTP/2 启用全都得你手动兜底。



















