在使用 Docker 部署应用时,我们有时会遇到一些意料之外的问题。例如,最近我在为域名 huayemao.run 配置 HTTPS 证书自动更新时,就遇到了一个由端口映射引起的 Certbot 认证失败问题。
问题描述
我通过 Docker 运行了一个 Next.js 应用容器,并将其映射到了宿主机的 80 端口。随后,当我尝试使用 Certbot(配合 Nginx 插件)为域名申请 SSL 证书时,出现了以下错误:
运行 sudo certbot --nginx -d huayemao.run
报错信息:
Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:Domain: huayemao.runType: unauthorizedDetail: 8.156.73.77: Invalid response from http://huayemao.run/.well-known/acme-challenge/U4dJGv4Gi7V2LumQBHFri-zGS9Kl3H2ks6ckBxLEwk0: 404Hint: The Certificate Authority failed to verify the temporary nginx configuration changes made by Certbot. Ensure the listed domains point to this nginx server and that it is accessible from the internet.
从错误信息可以看出,CA 在验证域名所有权时,尝试访问 http://huayemao.run/.well-known/acme-challenge/... 这个路径,但返回的却是 Next.js 应用的 404 页面,而非 Certbot 预期的认证文件。
问题原因
这是因为 Certbot 在验证域名时,需要临时接管 80 端口,并通过该端口响应 CA 发起的 HTTP 请求。然而,由于我的 Docker 容器已经占用了 80 端口,导致 Nginx 无法正常监听该端口,进而使得 CA 无法完成验证。
解决方案
解决这个问题的方法很简单:将 Docker 容器的映射端口从 80 改为其他端口(例如 3000),从而释放 80 端口供 Certbot 使用。
具体步骤如下:
-
停止并移除当前运行的容器(如果正在运行):
bashdocker stop <container_name>docker rm <container_name> -
重新启动容器,并映射到 3000 端口:
bashdocker run -d -p 3000:3000 --name <container_name> <
