接触Django,第一次撞墙了。google、百度了一晚上才搞明白。虽然python、django火了好几年,讲部署的文不少。很多博主都身经百战,对我这种小白,很多细节没有说到。这里把自己遇到的坑,以及部署的方法,整理出来,仅供参考。 在linux上搭建django部署环境,折腾了好几个小时。nginx、firewall、iptables、uwsgi一个个都不让人省心。
接触Django,第一次撞墙了。google、百度了一晚上才搞明白。虽然python、django火了好几年,讲部署的文不少。很多博主都身经百战,对我这种小白,很多细节没有说到。这里把自己遇到的坑,以及部署的方法,整理出来,仅供参考。 在linux上搭建django部署环境,折腾了好几个小时。nginx、firewall、iptables、uwsgi一个个都不让人省心。
这篇文章重点说明uwsgi与nginx的配置,至于其他,之后有时间在单独写出来,整合到这里。
网上关于django部署的文章不少,看多了难免有雷同的地方。后面的文,我尽量将自己遇到的难点写出来。不详尽的地方欢迎指出,欢迎加QQ群(709904667)
讨论。
如果使用mac电脑开发,建议在不了解部署wsgi的时候,先在本地进行uwsgi的部署测试。 我使用的开发环境OS 10.13.3 (17D47)。部署环境Centos 7.2。部署环境准备,当然要装好python(python3.6)、pip3、nginx、django。关闭firewall,安装iptables并开放80端口,以及用于django测试的端口(这里使用8000)。具体怎么做百度、google,或者等本懒哪天整理出来放到这里。(笑~)
Centos 7.2下安装python3一定会遇到yum异常的问题
,记得修复一下,以防以后安装时懵逼,参考vi /usr/bin/yum
,将第一行改为#!/usr/bin/python2.7
。python版本号看一下自己本机的python2版本号。
Centos 自带的firewall用得不习惯,以前也一直用的iptabls,果断换掉。
做完以上工作,浏览器
访问服务器可以看到nginx的默认页面,就算成功了。祝你幸福~
想通过nginx部署django,随便搜一下,都能看到一个叫做uwsgi的程序。uwsgi
是什么鬼?为啥不能像平时runserver直接运行,然后用nginx做个端口转发?
说到这里,就要先说明一下大多将python作为第二开发语言的人忽略的一个知识点——python 中的 WSGI
,官方描述点这里PEP 3333。
WSGI(the Python Web Server Gateway Interface)
最开始就是python中为了规范web服务开发定义的标准。作为一套标准接口,我们在这里只需要了解它的实现之一——Django!
Django实现了WSGI中定义的规范,可以监听端口,并返回对应的消息。所以我们才能通过python manage.py runserver
启动一个http服务。
本文提到的uwsgi,是一种实现了WSGI协议的服务器。我们这里可以使用uwsgi直接对接python程序实现http服务,也可以通过(重点)
uwsgi调用django中WSGI的实现,搭建与nginx通信的桥梁。
之后的两个小节,将介绍uwsgi的安装、测试、以及调起django的方法。
上面说了那么多,其实有pip的帮助,安装uwsgi
非常容易,一句代码搞定
pip install uwsgi
这一步不会报错,除非pip没有正确安装。另外不要用yum或apt-get命令安装,否则运行时得加很多参数。
搬一下砖,测试uwsgi的方法如下:
1、编写测试文件uwsgi_test.py,代码如下:
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"]
2、使用uwsgi启动python web服务
uwsgi --http :8000 --wsgi-file uwsgi_test.py
3、浏览器输入:http://127.0.0.1:8000,是不是看到亲切的Hello World了?什么没看到?换个端口试试,并检查uwsgi安装。
特别说明:
uwsgi执行时,如果应为程序或者配置问题,导致启动失败,很容易造成端口被占用,而且很难杀死。测试的时候请及时更换端口,避免浪费时间。
注意:这里可能会遇到很多问题,这里只说明必要操作。
有些关于uwsgi的说明中,让改django中的一个wsgi.py的文件。这里我要说django中,什么都不需要改。什么都不需要改!!!
另外有一些文中,uwsgi启动django的命令很复杂,类似上面uwsgi --http :8000 --wsgi-file uwsgi_test.py
这种。不需要!!!
我们只需要一个简单的配置文件,在网站项目根目录新建uwsgi.ini
,官方给出django的最简配置如下:
[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
wsgi-file = myproject/wsgi.py
processes = 4
threads = 2
stats = 127.0.0.1:9191
将本网站的配置拿出来分享下:
[uwsgi]
# socket = /zcm_web/zcm_blog/zcm_blog.sock
socket = 0.0.0.0:8001
master = true
chdir = /zcm_web/zcm_blog/
processes = 4
threads = 2
vacuum = true
pidfile = /zcm_web/zcm_blog/uwsgi.pid
wsgi-file = /zcm_web/zcm_blog/wsgi.py
daemonize = /zcm_web/zcm_blog/uwsgi.log
里面参数都是干什么的呢?请看官方说明。本懒才不会翻译呢~
简单说一下用到的参数:
socket:用于和nginx通信的端口设置。看官网意思是,这里可以是一个sock文件,因为本懒没用过,所以简单配置了一个端口供nginx桥接。
master:enable master process,主控程序可用?不知道什么鬼,以前间别人的配置文件有,貌似就加上了。
chdir:设置网站目录
processes:进程数,具体效果没有确定
threads:线程数,具体效果没有确定
vacuum:真空,嗯,一定是个好参数,加上。设置为true会在退出是,删除pid和socket文件。我这里只确认了对pid有效(因为没有用socket文件嘛)。
下面3个参数是重点,一定要配置对了
pidfile:pid文件位置,我直接指定到web根目录。uwsgi启动时会创建pid文件,用于uwsgi的重启和关闭。
wsgi-file:指定django的wsgi.py文件所在位置。
daemonize:指定log目录,不然哪里出错了都不知道。
配置成功之后,到网站根目录,输入 uwsgi uwsgi.ini
测试直接访问服务器该端口,不出问题的话应该可以访问了。有问题来群里讨论一下~
特别说明:
因为我使用的域名测试,需要在setting.py中修改ALLOWED_HOSTS
,不然没法访问。里面默认只有localhost
。
如果说上面uwsgi已经正确配置,那么接下来就是让nginx可以将请求转发到uwsgi了。我使用的本文为nginx 1.12.2,配置上推荐一下文件结构:
nginx
|
-conf.d #文件夹
|
-zcm_blog.conf
-nginx.conf
-其他文件
配置nginx.conf,在里面读取conf.d中的配置文件。这样每次新增网站或者服务,只需要在conf.d中增加一个文件,不必改动已有文件。 这里给出我的配置,nginx.conf:
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate "/etc/pki/nginx/server.crt";
# ssl_certificate_key "/etc/pki/nginx/private/server.key";
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
}
zcm_blog.conf配置如下:
server {
listen 80 ;
server_name www.imzcm.com;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8001;
}
location /static/ {
root /zcm_web/zcm_blog/;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
这些配置用了3年了,稳稳的。
zcm_blog.conf中uwsgi_pass
用于指定uwsgi启动的端口,要与之前配置文件中的socket保持一致~
配置之后执行nginx -s reload
加载配置,nginx不报错的话,就可以访问django网站了。
特别说明:
配置中发现比较容易出错的地方,为uwsgi.ini配置和zcm_blog.conf配置。先使用ip调试,没问题之后使用域名测试。
就到这里,在部署中挣扎的朋友要加油了~