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。

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

 

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

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

 

  1. [Unit] 
  2. Description=Gunicorn instance to server myapp 
  3. After=network.target 
  4.  
  5. [Service] 
  6. User=nginx  #这里的启动用户是关键
  7. Group=nginx 
  8. PrivateTmp=true 
  9. WorkingDirectory=/opt/myproject/Codes 
  10. Environment="PATH=/opt/myproject/venv/bin" 
  11. ExecStart=/opt/myproject/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 wsgi:app 
  12.  
  13. [Install] 
  14. WantedBy=multi-user.target 

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