一、问题背景
在使用 1Panel 部署 OpenResty 并创建一个静态网站后,发现:
- 使用域名访问 ❌ 无法打开
- 但本机 curl 测试 ✅ 正常
- 同时,用 Docker 单独启动一个 Nginx,域名却可以正常访问 ✅
这就导致一个非常迷惑的现象:
同一个域名,同一台服务器,不同方式部署,访问结果完全不同
二、初步排查思路
一开始优先排查常规问题:
1. 端口占用
ss -lntp | grep -E '80|443'
结果显示:
- 80 / 443 已被 OpenResty 正常监听 ✅
👉 排除端口冲突
2. Nginx 配置是否生效
检查站点配置:
server {
listen 80;
server_name ph-test.jinbokj.com.cn;
root /www/sites/ph-test.jinbokj.com.cn/index;
}
并通过本机测试:
curl -H "Host: ph-test.jinbokj.com.cn" http://127.0.0.1
返回:
恭喜,站点创建成功
👉 说明:
- OpenResty 正常运行 ✅
- server_name 匹配正常 ✅
- 站点配置无问题 ✅
三、关键异常点
当执行:
curl http://101.132.73.212
👉 请求直接卡住 ❌
这一步非常关键,说明:
服务器本机可以访问,但公网访问不通
四、最终定位:防火墙问题
执行:
firewall-cmd --list-ports
提示:
your connections/interfaces are in zone 'docker'
并且只开放了:
16484/tcp
👉 80 / 443 根本没有开放!
五、问题本质
流量路径对比
OpenResty(失败)
浏览器 → 公网 → firewalld(docker zone)❌ → OpenResty
👉 被防火墙拦截
Docker + Nginx(成功)
浏览器 → iptables(Docker规则)→ 容器Nginx ✅
👉 Docker 自动通过 iptables 转发流量
六、为什么 Docker 可以访问?
这是本次排查的核心认知:
Docker 会自动写入 iptables NAT 规则,绕过 firewalld 的端口限制
当执行:
docker run -p 80:80 nginx
Docker 会自动添加类似规则:
PREROUTING → DNAT → 容器IP:80
👉 流量在进入 firewalld 之前,就已经被转发走了
七、解决方案
正确方式(针对 1Panel + OpenResty)
开放 docker zone 端口:
firewall-cmd --zone=docker --add-port=80/tcp --permanent
firewall-cmd --zone=docker --add-port=443/tcp --permanent
firewall-cmd --reload
验证:
firewall-cmd --zone=docker --list-ports
八、验证结果
再次访问:
http://ph-test.jinbokj.com.cn
👉 页面正常打开 🎉
九、经验总结(重点)
1. 不要只看端口监听
ss -lntp
👉 只能说明“服务在监听”,不能说明“外网能访问”
2. 一定要区分访问路径
- 本机访问(127.0.0.1)
- 公网访问(域名/IP)
👉 两者完全不同
3. firewalld 的 zone 很重要
在 Docker 环境中:
firewall-cmd --get-active-zones
👉 很可能是 docker,而不是 public
4. Docker ≠ 遵守防火墙
Docker 会通过 iptables 改写流量路径
👉 表现出来就是:
- 端口没开放,但能访问
- 看起来像“绕过防火墙”
5. 标准生产建议
- 使用 OpenResty/Nginx 统一入口
- Docker 服务走内网端口(如 8080)
- 由反向代理转发
十、一句话总结
“能不能访问,不取决于服务是否启动,而取决于流量能不能走到它”
结尾
这次问题本质不是 Nginx 配置问题,而是:
网络路径 + 防火墙策略 + Docker 行为差异叠加导致的“假象问题”
理解这一点,对后续排查所有“能 curl 但打不开”的问题都会非常有帮助。
正文完
