Azure环境下Blacklabelops Let's Encrypt+Nginx配置故障求助
让我们一步步拆解问题,定位根源:
1. 先确认容器基础运行状态
首先用
docker ps查看Nginx容器是否正常运行,重点看端口映射是否显示0.0.0.0:80->80/tcp和0.0.0.0:443->443/tcp。如果容器没启动或者端口没绑定,直接看日志找错误:docker logs nginx常见错误比如端口冲突(之前的Nginx容器没停就重新启动)、配置文件语法错误、证书文件不存在。
另外注意:你步骤4的命令开头缺少了
sudo docker run -d,如果没加这个参数,容器不会后台运行,直接退出了,这是个容易忽略的点!
2. 检查Let's Encrypt证书是否正确生成
这里有个关键问题:你步骤1启动了Nginx容器占用80/443端口,步骤2又运行letsencrypt容器绑定同样的端口,这会导致端口冲突,letsencrypt容器根本启动失败,证书自然没生成!
修复&验证步骤:
- 先停掉并删除之前的Nginx容器:
sudo docker stop nginx && sudo docker rm nginx - 重新运行步骤2的letsencrypt安装命令,确保没有端口冲突。命令执行完成后,检查证书卷里的文件:
必须看到sudo docker run --rm -v letsencrypt_certificates:/etc/letsencrypt busybox ls -l /etc/letsencrypt/live/myapp.westeurope.cloudapp.azure.com/fullchain.pem和privkey.pem两个文件,否则证书生成失败。需要检查域名解析是否正常(用nslookup myapp.westeurope.cloudapp.azure.com确认域名指向你的Azure VM公网IP),或者ACME挑战是否被拦截。
3. 修正反向代理目标地址
你步骤4里的SERVER1REVERSE_PROXY_PASS1设置的是公网域名http://myapp.westeurope.cloudapp.azure.com,但你的Go应用是在宿主机的Docker容器里(端口8080),这种配置会让Nginx容器走公网去访问你的应用,不仅绕路,还可能被Azure网络规则拦截,甚至出现循环代理。
正确的做法是用容器内部的访问方式:
- 如果Go应用容器的IP是
172.17.0.2(你步骤1里用过这个IP),就改成:-e "SERVER1REVERSE_PROXY_PASS1=http://172.17.0.2:8080" - 更可靠的方式是给Go应用容器起个名字(比如
go-app),然后创建自定义Docker网络,把两个容器都加入进去,这样可以用容器名访问:# 创建自定义网络 sudo docker network create app-network # 启动Go应用容器时加入网络 sudo docker run -d --name go-app --network app-network -p 8080:8080 your-go-app-image # 启动Nginx容器时加入网络,并用容器名访问 sudo docker run -d \ -p 443:443 \ -p 80:80 \ --network app-network \ -v letsencrypt_certificates:/etc/letsencrypt \ -v letsencrypt_challenges:/var/www/letsencrypt \ -e "NGINX_REDIRECT_PORT80=true" \ -e "SERVER1REVERSE_PROXY_LOCATION1=/" \ -e "SERVER1REVERSE_PROXY_PASS1=http://go-app:8080" \ -e "SERVER1HTTPS_ENABLED=true" \ -e "SERVER1HTTP_ENABLED=true" \ -e "SERVER1LETSENCRYPT_CERTIFICATES=true" \ -e "SERVER1CERTIFICATE_FILE=/etc/letsencrypt/live/myapp.westeurope.cloudapp.azure.com/fullchain.pem" \ -e "SERVER1CERTIFICATE_KEY=/etc/letsencrypt/live/myapp.westeurope.cloudapp.azure.com/privkey.pem" \ -e "SERVER1CERTIFICATE_TRUSTED=/etc/letsencrypt/live/myapp.westeurope.cloudapp.azure.com/fullchain.pem" \ --name nginx \ blacklabelops/nginx
4. 验证ACME挑战路径是否正常
Let's Encrypt需要通过HTTP访问/.well-known/acme-challenge/路径来验证域名所有权,你步骤3挂载了letsencrypt_challenges卷,需要确认这个路径能正常访问:
- 在卷里创建一个测试文件:
sudo docker run --rm -v letsencrypt_challenges:/var/www/letsencrypt busybox echo "test" > /var/www/letsencrypt/.well-known/acme-challenge/test-file - 然后访问
http://myapp.westeurope.cloudapp.azure.com/.well-known/acme-challenge/test-file,如果能看到test内容,说明挑战路径配置正常;如果不行,检查Nginx容器的挑战路径配置,或者端口映射是否正确。
5. 再次确认Azure网络配置
虽然你说NSG开了端口,但再仔细核对:
- 入站规则是否允许所有来源(或者你测试用的IP)访问80和443端口,规则优先级是否高于拒绝规则;
- 虚拟机的公网IP是否正确绑定,域名解析是否指向这个IP(用
nslookup或者ping验证); - 虚拟机内部的防火墙(比如Ubuntu的ufw)是否允许80和443端口,运行
sudo ufw status查看,如果开启了ufw,需要添加规则:sudo ufw allow 80/tcp && sudo ufw allow 443/tcp。
6. 用curl做详细测试
用curl命令访问HTTPS,看具体错误信息:
curl -v https://myapp.westeurope.cloudapp.azure.com
- 如果显示
Connection timed out:大概率是网络问题(Azure NSG、虚拟机防火墙、公网IP绑定错误); - 如果显示
502 Bad Gateway:Nginx能正常接收请求,但反向代理到Go应用失败,检查容器间的网络连通性(进入Nginx容器用curl http://172.17.0.2:8080测试); - 如果显示证书错误:说明证书配置有问题,检查证书文件路径是否正确,文件是否存在。
内容的提问来源于stack exchange,提问作者mahu

