必须用mkcert生成并信任本地证书,禁用caddy_auto_https,挂载证书到容器并配置caddyfile显式tls指令;否则浏览器报net::err_cert_invalid。

在 macOS 上让 FrankenPHP v1.4 支持 HTTPS 本地访问,必须绕过 Let’s Encrypt 的公网验证限制,使用 mkcert 生成受信的本地证书,并确保 Caddy 正确加载、FrankenPHP 不触发自动 HTTPS 覆盖;直接设 SERVER_NAME=localhost 或用自签名 PEM 文件会导致浏览器报 NET::ERR_CERT_INVALID 且无法跳过。
第一步:安装 mkcert 并信任根证书
打开终端,依次执行:
brew install mkcert nss
mkcert -install
这一步会在 macOS 钥匙串中添加一个名为 “localhost” 的本地根证书(rootCA.pem),后续签发的证书才会被 Safari、Chrome 等浏览器标记为“安全”。【若跳过 -install,所有生成的证书都会被浏览器拦截,且无法手动忽略】
第二步:为 localhost 生成证书文件
在项目根目录下运行:
mkcert -cert-file cert.pem -key-file key.pem "localhost"
生成两个文件:cert.pem(含完整链)和 key.pem(私钥)。【不能改名、不能合并中间证书、不能用 openssl 自行生成——mkcert 是唯一能被 macOS 钥匙串自动信任的方案】
执行 ls -l 确认两个文件权限为 -rw-r--r--,无需 chmod 600(mkcert 默认不设私钥组/其他可读)。
第三步:挂载证书并禁用自动 HTTPS
启动 FrankenPHP 容器时,必须同时完成三件事:
① 用 -v 将 cert.pem 和 key.pem 挂载进容器内固定路径(如 /app/certs/)
② 在 Caddyfile 中显式声明 tls 指令,指向这两个文件
③ 设置环境变量 CADDY_AUTO_HTTPS=off,否则 Caddy 会无视你挂的证书,强行申请失败的公网证书
示例 docker run 命令:
docker run -p 8443:8443 -v $(pwd)/cert.pem:/app/certs/cert.pem -v $(pwd)/key.pem:/app/certs/key.pem -e CADDY_AUTO_HTTPS=off dunglas/frankenphp
第四步:编写启用 HTTPS 的 Caddyfile
在项目根目录新建 Caddyfile,内容如下:
{
servers { https_port 8443 }
}
localhost:8443 {
tls /app/certs/cert.pem /app/certs/key.pem
php_server
}
注意:https_port 必须写在全局块,否则 Caddy 仍监听 :443;localhost:8443 是完整监听地址,不能写成 :8443 或 localhost;tls 行路径必须与 -v 挂载路径完全一致。
第五步:验证 HTTPS 是否生效
容器启动后,在终端执行:
curl -kI https://localhost:8443
响应首行应为 HTTP/2 200(不是 HTTP/1.1),且 header 中包含 server: caddy。
在 Safari 或 Chrome 中访问 https://localhost:8443,地址栏左侧应显示灰色锁图标,点击可查看证书由 “localhost (mkcert)” 签发。
若看到 “此连接不是私密连接”,说明 mkcert -install 未成功,或证书路径写错,或 CADDY_AUTO_HTTPS=off 没生效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











