封尘网

让学习成为一种习惯!

Nginx反向代理Flask出现502问题一例

首先说明一下,这个问题并不适合所有报这个错误的示例。本文的部署方法可以参考上一篇文章:

Centos7 安装Python3.6+Nginx+Gunicorn+Flask

错误提示:

Failed to load resource: the server responded with a status of 502 (Bad Gateway)

项目运行环境:
系统:CentOS Linux release 7.2.1511 (Core)
python:3.5.2
virtualenv:15.2.0
gunicorn:19.7.1
Nginx:1.12.2

为了方便公司统计gitlab上项目的代码贡献量,我特意写了一个Flask程序+python程序来执行。默认python-gitlab API可以拿到很多数据,但是不能统计到每个用户增加、移除代码行数。所以通过了python的一个脚本来拉取代码下来并利用git log来统计代码的增、删行数。而为了方便我直接在flask上通过选择项目和分支,通过post提交后写入到配置文件:t.json中,而python脚本文件就是通过t.json来拉取项目指定定分支 的代码,统计完后写入到数据库中,方便flask调用。

由于直接执行启动flask项目是可以正常写入文件,并返回成功状态。但是部署到Centos系统上就出现了502状态码,所有请求的路径和方法都一样的。查看Nginx日志也找不出原因,最后通过对比发现可能是写文件时没有权限导致的。

解决思路,查看是哪个程序以什么用户运行:

下面是systemctl start myapp启动的,注意这里的用户是配置了Nginx。

(venv) [root@docker Codes]# lsof -i:8000  
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME  
gunicorn 825 nginx    6u  IPv4 942272      0t0  TCP localhost:irdmi (LISTEN)  
gunicorn 829 nginx    6u  IPv4 942272      0t0  TCP localhost:irdmi (LISTEN)  
gunicorn 830 nginx    6u  IPv4 942272      0t0  TCP localhost:irdmi (LISTEN)  
gunicorn 831 nginx    6u  IPv4 942272      0t0  TCP localhost:irdmi (LISTEN)

而使用gunicorn wsgi:app 启动时的情况如下,这里使用的是root用户。

[root@docker ~]# lsof -i:8000 
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME 
gunicorn 850 root    6u  IPv4 942510      0t0  TCP localhost:irdmi (LISTEN) 
gunicorn 853 root    6u  IPv4 942510      0t0  TCP localhost:irdmi (LISTEN) 


[Unit] 
Description=Gunicorn instance to server myapp 
After=network.target 

[Service] 
User=nginx      #这里的启动用户是关键
Group=nginx 
PrivateTmp=true 
WorkingDirectory=/opt/myproject/Codes 
Environment="PATH=/opt/myproject/venv/bin" 
ExecStart=/opt/myproject/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 wsgi:app 

[Install] 
WantedBy=multi-user.target

最后把配置文件的运行用户改成root后就可以正常写入了。但是为了安全,还是建议另一个方法就是保存的文件t.json权限所有者改成Nginx。

提醒:本文最后更新于 551 天前,文中所描述的信息可能已发生改变,请谨慎使用。