nginx 发音engine-x,是一个免费开源并且高性能的HTTP服务器和反向代理,还是一个IMAP/POP3代理服务器。
WSGI,Web服务器网关接口(Web Server Gateway Interface)。一个web服务器面对的是外部世界。它能直接从文件系统提供文件 (HTML, 图像, CSS等等)。然而,它无法 *直接*与Django应用通信;它需要借助一些工具的帮助,这些东西会运行运用,接收来自web客户端(例如浏览器)的请求,然后返回响应。WSGI就是干这活的,uWSGI是一种WSGI实现。
备注:在这个教程中,假设域名为example.com 。可以使用FQDN或者IP地址来代替。

基本的uWSGI安装和配置

安装uwsgi

pip install uwsgi

基础测试test.py

创建名为test.py文件:

  1. # test.py
  2. def application(env, start_response):
  3. start_response('200 OK', [('Content-Type','text/html')])
  4. #return [b"Hello World"] # python3
  5. return ["Hello World"] # python2

运行uWSGI:
uwsgi --http :8000 --wsgi-file test.py
http :8000:使用http协议,端口8000
wsgi-file test.py: 加载指定的文件,test.py
使用浏览器访问http://example.com:8000或者http://localhost:8000,浏览器窗口出现“hello world”消息,说明以下组件栈工作正常:

the web client <-> uWSGI <-> Python

测试django项目

假设django工程mysite已经建好,进入django工程目录,与manage.py文件同级目录。使用uwsgi运行工程:
uwsgi --http :8000 --module mysite.wsgi
如果站点正常访问,说明以下栈正常工作:

the web client <-> uWSGI <-> Django

基本的nginx

安装nginx

sudo apt-get install nginx
sudo /etc/init.d/nginx start #启动nginx服务器
在浏览器通过80端口访问,出现“welcome to nginx”说明以下栈正常工作(如果已经有程序提供端口80的服务,并且你想要在那里使用nginx,那么你将必须重新配置nginx来提供另一个端口的服务):

the web client <-> the web server

为站点配置nginx

将文件uwsgi_params.zip解压后放在django工程目录中,并在同级目录下创建mysite_nginx.conf文件,并写入以下内容。

  1. # mysite_nginx.conf
  2. # the upstream component nginx needs to connect to
  3. upstream django {
  4. # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
  5. server 127.0.0.1:8001; # for a web port socket (we'll use this first)
  6. }
  7. # configuration of the server
  8. server {
  9. # the port your site will be served on
  10. listen 8000;
  11. # the domain name it will serve for
  12. server_name .example.com; # substitute your machine's IP address or FQDN
  13. charset utf-8;
  14. # max upload size
  15. client_max_body_size 75M; # adjust to taste
  16. # Django media
  17. location /media {
  18. alias /path/to/your/mysite/media; # your Django project's media files - amend as required
  19. }
  20. location /static {
  21. alias /path/to/your/mysite/static; # your Django project's static files - amend as required
  22. }
  23. # Finally, send all non-media requests to the Django server.
  24. location / {
  25. uwsgi_pass django;
  26. include /path/to/your/mysite/uwsgi_params; # the uwsgi_params file you installed
  27. }
  28. }

这个文件提供来自文件系统的媒体和静态文件,该文件也可以在github上下载。将配置文件链接到/etc/nginx/sites-enabled,这样nginx就可以看到它:
sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/

部署静态文件

编辑mysite/settings.py,添加如下内容:

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

运行命令python manage.py collectstatic

测试nginx

重启nginx:
sudo /etc/init.d/nginx restart
把图像media.png放到/path/to/your/project/project/media directory中,访问http://example.com:8000/media/media.png,如果图像在浏览器正常显示,说明nginx能提供文件服务

nginx和uWSGI以及test.py

启动WSGI服务:
uwsgi --socket :8001 --wsgi-file test.py
socket :8001: 使用uwsgi协议,端口为8001
在mysite_nginx.conf文件,已经配置了nginx在8001端口与uWSGI通信,而对外使用8000端口,在浏览器中访问地址[http://example.com:8000/](http://example.com:8000/),输出”hello world”,说明以下栈正常工作:

the web client <-> the web server <-> the socket <-> uWSGI <-> Python

使用Unix socket而不是端口

使用Unix socket会比端口更好,开销更少。修改mysite_nginx.conf。

server unix:///path/to/your/mysite/mysite.sock; # for a file socket
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)

重启nginx: sudo /etc/init.d/nginx restart
运行uWSGI: uwsgi --socket mysite.sock --wsgi-file test.py
浏览器中访问http://example.com:8000/,一般会报错。检查nginx错误日志/var/log/nginx/error.log,会得到如下错误信息:

connect() to unix:///path/to/your/mysite/mysite.sock failed (13: Permission
denied)

要使nginx正确读取和写入socket,使用以下命令运行uWSGI:
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666 # (very permissive)
或者:
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664 # (more sensible)

使用uwsgi和nginx运行Django应用

在django工程目录下运行:
uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664

配置uWSGI以允许.ini文件

可以将用在uWSGI上的相同的选项放到一个文件中,然后告诉 uWSGI使用该文件运行。这使得管理配置更容易。
创建名为mysite_uwsgi.ini的文件:

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /path/to/your/project
# Django's wsgi file
module          = project.wsgi
# the virtualenv (full path)
#home            = /path/to/virtualenv

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /path/to/your/project/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 666
# clear environment on exit
vacuum          = true

使用文件运行uSWGI:
uwsgi --ini mysite_uwsgi.ini # the --ini option is used to specify a file
在浏览器中测试站点是否正常工作。

Emperor模式

uWSGI可以运行在’emperor’模式。在这种模式下,它会监控uWSGI配置文件目录,然后为每个它找到的配置文件生成实例 (‘vassals’)。每当修改了一个配置文件,emperor将会自动重启 vassal.

# create a directory for the vassals
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
# symlink from the default config directory to your config file
sudo ln -s /path/to/your/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/
# run the emperor
sudo uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
#sudo uwsgi --emperor /etc/uwsgi/vassals

emperor: 查找vassals (配置文件)的地方
uid: 进程一旦启动后的用户id
gid: 进程一旦启动后的组id
实例:sudo uwsgi --emperor /etc/uwsgi/vassals --uid pi --gid sudo

系统启动时运行uWSGI

编辑 /etc/rc.local 然后在”exit 0”行前添加:

/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log

总结:使用django,uwsgi,nginx部署web应用程序主要步骤

安装uwsgi

sudo pip install uwsgi

安装nginx

sudo apt-get install nginx
sudo /etc/init.d/nginx start #启动nginx服务器

配置nginx

将文件uwsgi_params.zip解压后放在django工程目录中,并在同级目录下创建mysite_nginx.conf文件,并写入以下内容。

# mysite_nginx.conf

# the upstream component nginx needs to connect to
upstream django {
    server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    #server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name .example.com; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    # Django media
    location /media  {
        alias /path/to/your/mysite/media;  # your Django project's media files - amend as required
    }

    location /static {
        alias /path/to/your/mysite/static; # your Django project's static files - amend as required
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /path/to/your/mysite/uwsgi_params; # the uwsgi_params file you installed
    }
}

将配置文件链接到/etc/nginx/sites-enabled:
sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/

部署静态文件

编辑mysite/settings.py,添加如下内容:

STATIC_ROOT = os.path.join(BASE_DIR, "static/")

运行命令python manage.py collectstatic

配置uWSGI

在django工程目录中创建mysite_uwsgi.ini文件:

# mysite_uwsgi.ini file
[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /path/to/your/project
# Django's wsgi file
module          = project.wsgi
# the virtualenv (full path)
#home            = /path/to/virtualenv

# process-related settings
# master
master          = true
# maximum number of worker processes
processes       = 10
# the socket (use the full path to be safe
socket          = /path/to/your/project/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 666
# clear environment on exit
vacuum          = true

配置emperor模式

sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals
sudo ln -s /path/to/your/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/

启动服务器

重启nginx服务器:sudo /etc/init.d/nginx restart
运行uWSGI:sudo uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data或者sudo uwsgi --emperor /etc/uwsgi/vassals

开机自启动

编辑 /etc/rc.local 然后在”exit 0”行前添加:

/usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log

参考文档

使用uWSGI和nginx来设置Django web服务器
Setting up Django and your web server with uWSGI and nginx