使用Flask+Gunicorn+Nginx在Linux进行网站部署

本文首发于我的博客:http://gongyanli.com/
代码传送门:https://github.com/Gladysgong/flask_scrapy_aiot
: https://www.jianshu.com/p/7da2e5892dd6
CSDN: https://blog.csdn.net/u012052168/article/details/79985613
一、前言 这个网站部署属于很心酸的过程,至于如何心酸我必须得说出来,给我自己的时间一个交代。开始我使用Flask+uWsgi+Nginx进行配置的,哪哪儿都配置好了,Nginx欢迎页也可以访问,Flask本身也没问题,但就是uWsgi访问不了。
因为哪里配置都没问题,但就是无法访问,我Google、baidu各种查了好久,都解决不了。有说权限问题的,但是我都换到root下了,有说哪里哪里加个plugins的,对于我还是不行。后来我看见有人说,他也遇到这个问题解决不了,后来他就搁置不弄了,过了一星期左右,打开
自己就连接上了。于是我想了想,对于这种我该放弃了。
网上看了看,说Gunicorn比uWsgi好用,于是我就换成了Gunicorn,然后分分钟成功,可是我却在这上面干耗了一天。
顺便提一下,代码中flask_aiot为网站文件,scrapy_aiot是我的爬虫文件,用来抓取网站所用的数据,有兴趣可以看一下,当时写的好像不是很完善,有不对的地方留言告诉就ok,我改。
二、环境和目录结构
Centos7 Python3 Flask:是一个用Python实现的Web开发的微服务框架 Guicorn:Web服务器,和UWsgi类似 Nginx:反向代理

flask_aiot ├── app ├── config.py ├── manage.py ├── requirements.txt └── venv ├── bin ├── include ├── lib └── share

三、安装基础环境 【使用Flask+Gunicorn+Nginx在Linux进行网站部署】我用的是Python3,而现在Centos下默认的还是Python2,所以我用Anaconda安装了一个Python3,很方便。
不同的项目可能会需要不同的依赖包,所以我用了VirtualEnv来管理依赖。
pip install virtualenv 创建虚拟环境并激活 [root@localhost flask_aiot]# source venv/bin/activate

四、安装Flask
直接在虚拟环境下安装requirements.txt即可,一次性把依赖都安装齐全。 (venv) [root@localhost flask_aiot]# pip install -r requirements.txt

五、项目文件 在生产环境中,我们的Flask项目是做在包内的,在包外采用Flask Script写一个manage.py文件作为启动文件,这样方便支持各种项目。manage.py文件如下:
` #!/usr/bin/env python import osif os.path.exists('.env'): print('Importing environment from .env...') for line in open('.env'): var = line.strip().split('=') if len(var) == 2: os.environ[var[0]] = var[1]# from app import create_app, db from app import create_app, mongo from app.models import User, AllProductPrice, Ny135, Chinacwa, Iot from flask_script import Manager, Shell from flask_migrate import Migrate, MigrateCommandapp = create_app(os.getenv('FLASK_CONFIG') or 'default') manager = Manager(app) migrate = Migrate(app, mongo)def make_shell_context(): return dict(app=app, db=mongo, User=User, AllProductPrice=AllProductPrice, Ny135=Ny135, Chinacwa=Chinacwa, Iot=Iot)manager.add_command("shell", Shell(make_context=make_shell_context)) manager.add_command('db', MigrateCommand)@manager.command def test(): """Run the unit tests.""" import unittest tests = unittest.TestLoader().discover('tests') unittest.TextTestRunner(verbosity=2).run(tests)if __name__ == '__main__': manager.run() `

此时我们可以直接在虚拟环境中运行Flask:
默认地址和端口启动: (venv) [root@localhost flask_aiot]# python manage.py runserver 任意地址和8099端口启动: (venv) [root@localhost flask_aiot]# python manage.py runserver -h 0.0.0.0 -p 8099 运行: curl i 127.0.0.1:8099# 看到网站返回的内容

六、安装Gunicorn Flask的生产环境比较成熟的有Gunicorn和uWSGI,无奈我一直配置uWSGI不成功,所以换成了Gunicorn,而且和uWSGI相比起来,Gunicorn的配置真的蛮简单的。
(venv) [root@localhost flask_aiot]# pip install gunicorn 运行: (venv) [root@localhost flask_aiot]# gunicorn -w 4 -b 127.0.0.1:8001 manage:app curl i 127.0.0.1:8001# 看到网站返回的内容

七、Nginx 1、安装
网上好多用yum install nginx来进行安装的,但是目前centos7上已经不支持了,所以我用安装包进行安装的。

2、配置文件
vi /etc/nginx/conf.d/default.confdefault.conf如下: server { listen8099; server_name10.200.116.13; # server_name111.203.20.92; location / { #include uwsgi_params; #uwsgi_pass127.0.0.1:8001; # 指向uwsgi 所应用的内部地址,所有请求将转发给uwsgi 处理 #uwsgi_param UWSGI_PYHOME /home/lilly/www/flask_scrapy_aiot/flask_aiot/venv; # 指向虚拟环境目录 #uwsgi_param UWSGI_CHDIR/home/lilly/www/flask_scrapy_aiot/flask_aiot; # 指向网站根目录 #uwsgi_param UWSGI_SCRIPT manage:app; # 指定启动程序 #uwsgi_read_timeout 100; proxy_pass http://localhost:8001; proxy_redirectoff; proxy_set_headerHost$host; proxy_set_headerX-Real-IP$remote_addr; proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for; proxy_set_headerX-Forwared-Proto$scheme; #root/usr/share/nginx/html; #indexindex.html index.htm; }

vi /etc/nginx/nginx.conf nginx.conf如下: usernginx; worker_processes1; error_log/var/log/nginx/error.log warn; pid/var/run/nginx.pid; events { worker_connections1024; }http { include/etc/nginx/mime.types; default_typeapplication/octet-stream; log_formatmain'$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.logmain; sendfileon; #tcp_nopushon; keepalive_timeout65; #gzipon; include /etc/nginx/conf.d/*.conf; # 这句话很重要,相当于引入了上面的default.conf配置文件 }

3、重启Nginx
sudo service nginx restart sudo systemctl restartnginx.service 我用以上方式启动的时候总是提示:Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details. 我查看的时候说:nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied) 但是我都是用root来启动的了,不应该存在这种问题啊。 所以我是直接nginx这样启动的,确实nginx是起来了的。

4、访问网站
curl i 10.200.116.13:8099# 返回网站内容

八、Supervisor 如果想要当进程意外关闭后能自动重启,应该再配置一个Supervisor来实现。目前Supervisor只支持Python2,我看官方说目前Python3已经在进行中,应该很快就能支持了。我在这个部署里就没做这块了,即使在Python3下面也可以用Supervisor,因为他只是调进程而已,想做的话可以网上找找文档,不难。
九、后续 Nginx等一系列部署好后,我打开网站还发现了一个bug,当然这是我程序的问题。bug如下:
当我10.200.116.13:8099时停留在首页,当我点击网站的某一按钮,跳转到另一个页面,出现404错误,而此时我看网站的url为 10.200.116.13/show 这也就意味着网站跳转时没把8099的端口给带上,而我手动在地址栏输入10.200.116.13:8099/show时,页面是能够正常显示的。 说明8099的端口有些地方是静态的,没有动态更着走。把下面的语句1改为语句2就可以了。

语句1:
  • 中国农业物联网
  • #}语句2:
  • 中国农业物联网

    • 推荐阅读