记录一次Nginx使用的坑
情况描述
https甲方配置了已经绑定到我们8082端口了,Nginx如何配才能让自己的请求通过这个端口在本地无证书的情况下变成https。
使用环境
Docker安装最新版Nginx,并映射到各自的80端口,做好了文件映射
1
| docker run -p 80:80 --name nginx --restart=always -v /opt/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /opt/docker/nginx/conf.d:/etc/nginx/conf.d -v /opt/docker/nginx/html:/usr/share/nginx/html -v /opt/docker/nginx/logs:/var/log/nginx -d nginx
|
坑一
不论怎么配置80端口的代理,永远不生效,指定root目录后依旧是展示Nginx启动页,换了资源目录、配置全局root、换成alias都无效。以下是配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| http { include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf; root /user/share/nginx/html/buildingNavigationFront; server{ listen 80; listen [::]:80; server_name 12;
location / { root /usr/share/nginx/html/buildingNavigationFront; index index.html index.htm; add_header Content-Type "text/plain;charset=utf-8"; add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Methods' 'GET, POST'; }
}
}
|
然而,原因很简单
1
| include /etc/nginx/conf.d/*.conf;
|
这句话指定了一个默认配置文件,打开这个默认配置文件会发现它自己代理了80端口,所以你的配置会被他覆盖,永远无法生效。这其实是Docker的锅,他会自动把这个配置写进去,但是在服务器里直接yum安装Nginx是不会有这项默认配置的。
坑二
解决了坑一后,代理80端口转发到8082,指定访问8082端口返回的资源目录。重启Nginx,终于不是Nginx的启动页面了,变成了长时间未响应的错误信息返回页。呵呵了。
在把搜索引擎敲烂后,终于找到了原因。其实也很简单,但是也很容易疏忽。
如下图,由于Docker容器化部署的特性,使用Nginx代理并映射80端口后,转发到的是Nginx容器下的资源目录和端口,所以如果这个Nginx容器下的目录和配置文件的目录对不上,就会导致错误。此外,如果配置的目录在服务器而不在容器,就需要在nginx.conf把代理地址设置为服务器的公网ip地址,而不是localhost,否则会转发到容器里去。

坑三
类似坑二,https甲方配置了已经绑定到我们8082端口了,但是代理之后通过80访问依旧无效。配置大概如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| server{ listen 80; server_name localhost; location / { add_header X-Frame-Options ALLOWALL; proxy_pass http://localhost:8082/; } } server{ listen 8082; server_name xxxxxxx.com; location / { root /user/share/nginx/html; index index.html index.htm;
}
}
|
坑二已经说过了,这是会转发到Nginx容器里去的,所以proxy_pass对应的地址应该是公网ip的8082端口,而不是localhost。
修改之后,依旧不行,此时已临近崩溃边缘。冷静下后,想到是说不定是防火墙的问题。
1
| firewall-cmd --zone=public --list-ports
|
果然,列出的端口里没有80(明明之前开了)和8082。
1 2
| firewall-cmd --add-port=80/tcp --permanent firewall-cmd --reload
|
打开端口之后在测试,大概率应该已经成功
自己的解决方案
为什么说大概率呢,因为到达那步之后,我依然没有达到目标,但是这时的配置我自己已经找不出逻辑上的问题了,可能是配置乱了。最后总结出一个结论,不要用Docker去安装代理类的中间件。我已经放弃使用Docker来部署Nginx了,最后干脆删除了整个Nginx容器。直接在本地部署Nginx。
本地部署完Nginx,安装编译后,打开/usr/local/nginx/conf/nginx.conf(默认路径),发现没有坑一说到的默认配置,舒服。配置好80端口和8082端口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| http { include mime.types; default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server { listen 80; server_name localhost;
location / { proxy_pass http://localhost:8082; }
}
server { listen 8082; server_name xxxxxxx.com; location /navigator { proxy_pass http://localhost:8020; } location / { root /opt/docker/nginx/html; index index.html index.htm; } }
}
|
访问https://xxxxxxx.com/资源目录
成功本地无证书配置https
