Flask:在Centos上配置两个Flask项目

源于

一开始我是只有一个项目的,非常好配置,而且也简单。但是后来发现,又有一个新项目需要新增上去。结果配置搞了好几天,今天终于搞定。(在网上的提问

其实精髓很简单,配置两个类似的就行,端口,日志文件,项目路径分开就行。

在这里不谈如何安装环境,关于安装环境可以参考(地址)。

Python flask
image-2417

开始操作

这里使用:Nginx + Uwsgi + virtualenv 进行配置操作.

首先是要配置Nginx,那么安装好之后,Nginx一般是在/usr/local/nginx这个目录下面,配置文件则在/usr/local/nginx/conf下面,因为我们需要配置多个站点,因此需要新建/usr/local/nginx/conf/vhost目录,然后把相关文件放在这个目录下面即可.

首先看nginx.conf的文件[/usr/local/nginx/conf/nginx.conf]:
下面这个配置文件基本只是改动了几个地方,第一行需要注意,这是使用www用户进行操作.所以需要新建用户.另外就是
include /usr/local/nginx/conf/vhost/*.conf;很关键,这一行表示加载vhost目录下面所有conf结尾的文件(在Nginx上配置子站点就是这样操作的).

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
user  www;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       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  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}
include   /usr/local/nginx/conf/vhost/*.conf;
}

下面是子站点A的conf[目录:/usr/local/nginx/conf/vhost/A.conf]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 server {
        listen       80;
        server_name  A;
        #charset koi8-r;
        access_log  /var/www/venv/logs/access.log;
        error_log  /var/www/venv/logs/error.log;

        location / {
            include        uwsgi_params; # 引入
            uwsgi_pass     127.0.0.1:3031;# 监听端口,此处不同
            uwsgi_param UWSGI_PYHOME /var/www/venv/A;# 项目根目录,此处不同
            uwsgi_param UWSGI_CHDIR  /var/www/venv;# venv虚拟根目录
            uwsgi_param UWSGI_SCRIPT main:app; # 启动文件和Flask实例名称(通常都是app)
        }
    }

下面是子站点B的conf[目录:/usr/local/nginx/conf/vhost/B.conf]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 server {
        listen       80;
        server_name  A;
        #charset koi8-r;
        access_log  /var/www/venv/logs/access.log;
        error_log  /var/www/venv/logs/error.log;

        location / {
            include        uwsgi_params; # 引入
            uwsgi_pass     127.0.0.1:8081;# 监听端口,此处不同
            uwsgi_param UWSGI_PYHOME /var/www/venv/B;# 项目根目录,此处不同
            uwsgi_param UWSGI_CHDIR  /var/www/venv;# venv虚拟根目录
            uwsgi_param UWSGI_SCRIPT main:app; # 启动文件和Flask实例名称(通常都是app)
        }
    }

配置文件都搞定之后,新建/var/www/venv目录,使用mkdir /var/www/venv -p.之后virtualenv A 创建虚拟环境A,完成之后,virtualenv B创建虚拟环境B.都依次创建完之后,分别在项目根目录[就是A,B两个目录]里面新建一个main.py文件.

切换到A目录,使用cd A .

main.py[目录:/var/www/venv/A]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python3
# coding=utf-8
# -*-coding:utf-8-*-

from flask import Flask


app = Flask(__name__)


@app.route('/')
def show():
    return "A.............."


if __name__ == '__main__':
    app.run()

之后需要创建一个xml配置文件,指出如何初始化A项目.
文件:app_config.xml[目录:/var/www/venv/A/]
下面的文件不能有空格,切记切记!!!

1
2
3
4
5
6
7
8
9
<uwsgi>
<pythonpath>/var/www/venv/A</pythonpath>
<module>main</module>
<callable>app</callable>
<socket>127.0.0.1:3031</socket>
<master/>
<processes>4</processes>
<memory-report/>
</uwsgi>

至此,A项目创建完成.

接着来B项目.切换到B目录,使用cd ../B

main.py[目录:/var/www/venv/B]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python3
# coding=utf-8
# -*-coding:utf-8-*-

from flask import Flask


app = Flask(__name__)


@app.route('/')
def show():
    return "B.............."


if __name__ == '__main__':
    app.run()

之后需要创建一个xml配置文件,指出如何初始化B项目.
文件:app_config.xml[目录:/var/www/venv/B/]
下面的文件不能有空格,切记切记!!!

1
2
3
4
5
6
7
8
9
<uwsgi>
<pythonpath>/var/www/venv/B</pythonpath>
<module>main</module>
<callable>app</callable>
<socket>127.0.0.1:8081</socket>
<master/>
<processes>4</processes>
<memory-report/>
</uwsgi>

至此,B项目创建完成.

都搞定之后,可以写一个启动脚本.
如下[startserver.sh]:

1
2
3
4
5
6
7
#!/bin/bash
# Startup script for the nginx Web Server
# ?P.~J?wsgi
/usr/local/python3.4/bin/uwsgi -x /var/www/venv/A/app_config.xml -d /var/log/uwsgi/uwsgiA.log --pidfile /tmp/uwsgiA.pid
/usr/local/python3.4/bin/uwsgi -x /var/www/venv/B/app_config.xml -d /var/log/uwsgi/uwsgiB.log --pidfile /tmp/uwsgiB.pid
# 启动nginx
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

之后使用chmod +x startserver.sh 即可启动.

总结

一共使用了如下目录或文件:

Nginx

服务器配置文件:
/usr/local/nginx/conf/nginx.conf
/usr/local/nginx/conf/vhost/A.conf
/usr/local/nginx/conf/vhost/B.conf

Flask

项目文件[项目中还有其它自动生成的文件,忽略不计]:
/var/www/venv/A/app_config.xml
/var/www/venv/A/main.py
/var/www/venv/B/main.py
/var/www/venv/B/app_config.xml

之后就是启动脚本了,可以放在你想放的地方,比如/pyscript/startserver.sh,到此,大功告成!

参考: