目前,很多Python的web框架,如Flask,Django等,在生产环境一般是通过web服务器(比如Apache HTTPd,Nginx)+uwsgi构成的,本篇主要是讲解这个环境的搭建过程。本机IP:192.168.42.15。机器名:template。我们预计建两个demo,一个用正常的80端口,一个用8080端口,两个demo的工作目录分别是/srv/demo1,/srv/demo2。由于我们只是在内网测试,就不采用域名访问这两个demo了。
安装Nginx:
首先,我们需要安装epel软件仓库:
yum install epel-release
接下来安装Nginx:
yum install nginx
epel上面的nginx是最新的稳定版1.10.2,非常好用,博主一般不推荐自己编译的版本。
把Nginx加入开机启动:
systemctl enable nginx.service
防火墙把80和8080端口打开:
firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-port=8080/tcp firewall-cmd --reload
安装uwsgi:
yum install uwsgi uwsgi-plugin-python
把uwsgi加入开机启动:
systemctl enable uwsgi.service
安装flask:
yum install python-flask
正式配置阶段
建立两个demo的工作目录:
mkdir /srv/{demo1,demo2}
改变下所有者:
chown uwsgi:uwsgi /srv/{demo1,demo2}
设置下selinux上下文:
semanage fcontext -a -t httpd_sys_rw_content_t "/srv/demo1(/.*)?" semanage fcontext -a -t httpd_sys_rw_content_t "/srv/demo2(/.*)?"
分别cd到demo1文件夹中,建立一个示例文件,vim test1.py,内容如下:
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "<h1 style='color:blue'>This is demo1 site!</h1>" if __name__ == "__main__": app.run(host='0.0.0.0')
再进入demo2目录,vim test2.py,把上面代码的输出内容改成“This is demo2 site!”便于区分。
新建两个配置文件:
vim /etc/uwsgi.d/demo1.ini,内容如下:
[uwsgi] plugin = python base = /srv/demo1 chdir = /srv/demo1 module = test1 pythonpath = %(base) socket = %(base)/%n.sock chmod-socket = 666 callable = app logto = /var/log/%n.log
这里的socket权限设置为666主要是socket本身的属主是uwsgi用户,需要被nginx读写,所以我们设置了666权限。接下来改变下次配置文件的属主:
chown uwsgi:uwsgi demo1.ini
生成下日志文件:
touch /var/log/demo1.log chown uwsgi:uwsgi /var/log/demo1.log
再建一个配置文件vim /etc/uwsgi.d/demo2.ini,把上述配置文件中的demo1,test1,改成demo2,test2,即可,权限也按照这个原理改变下。
新建nginx虚拟主机vim /etc/nginx/conf.d/demo1.conf
server { listen 80; server_name 192.168.42.15; # root /srv/demo1; charset utf-8; client_max_body_size 75M; location / { try_files $uri @test1; } location @test1 { include uwsgi_params; uwsgi_pass unix:/srv/demo1/demo1.sock; } }
再生成一个虚拟主机vim /etc/nginx/conf.d/demo2.conf
server { listen 8080; server_name 192.168.42.15; # root /srv/demo2; charset utf-8; client_max_body_size 75M; location / { try_files $uri @test2; } location @test2 { include uwsgi_params; uwsgi_pass unix:/srv/demo2/demo2.sock; } }
注意,我们这里没有通过域名主机头来访问测试网站,直接用ip和端口号来限制访问。如果你有域名,或者通过修改hosts文件,也可以通过域名来访问测试网站,有域名的话,就不用单独设置8080的端口了,统一用80端口即可。
分别打开http://192.168.42.15/和http://192.168.42.15:8080/,可以看到我们期待的内容了。
补充内容:如果我们的web程序不仅仅是python程序,还有类似js,css,jpg等静态内容,可以再nginx配置中配置动静分离,以提高性能。例如,如果你的图像文件统一放在了demo1下的images文件夹来,所有请求中以/images路径请求的,我们可以这样添加配置:
location /images/ { root /srv/demo1/; }
或者用别名可以这样处理:
location /images/ { alias /srv/demo1/images/; }
因为images文件夹本来就在默认的root目录下,所以此处的root和alias路径其实不是必须的。
如果想对特定的文件,例如js,css文件进行配置,可以这样:
location ~* \.(js|css)$ { root /path1; expires 1h; } location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ { root /path2; expires 30d; }
location后面跟~,代表后面跟的是一个正则表达式,且区分大小写,~*表示后面跟的是不区分大小写的正则表达式。如果location下规则较多的话,注意规则的先后顺序。
另外需要注意的是,目前CentOS7上,uwsgi和nginx启动的顺序有点问题,会导致有些网站无法登录的情况,解决的方法是让uwsgi在nginx服务启动后再启动。
vim /usr/lib/systemd/system/uwsgi.service ... After=syslog.target nginx.service ...
然后重新加载下:
systemctl daemon-reload