使用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

三、安装基础环境

我用的是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 os

if 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, MigrateCommand


app = 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.conf

default.conf如下:
server {
    listen       8099;
    server_name  10.200.116.13;
    # server_name  111.203.20.92;

    location / {
      #  include uwsgi_params;
      #  uwsgi_pass  127.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_redirect          off;
        proxy_set_header        Host                    $host;
        proxy_set_header        X-Real-IP               $remote_addr;
        proxy_set_header        X-Forwarded-For         $proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwared-Proto        $scheme;
      #  root   /usr/share/nginx/html;
      #  index  index.html index.htm;
    }

vi /etc/nginx/nginx.conf 

nginx.conf如下:
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


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;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;   # 这句话很重要,相当于引入了上面的default.conf配置文件
}

3、重启Nginx

sudo service nginx restart
sudo systemctl restart  nginx.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:<li><a href="/show_ny135" class="hvr-sweep-to-bottom">中国农业物联网</a></li>#}

语句2:<li><a href="{{ url_for('main.ShowNy135View') }}" class="hvr-sweep-to-bottom">中国农业物联网</a></li>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容