L
Published on
· Last modified on
· Public

Django Web 应用使用 uWSGI、Nginx 部署至 Debian 服务器

0. 原理

nginx 作为服务器最前端,接受所有请求。静态请求,媒体文件由 Nginx 处理,非静态请求由 uWSGI 通过 Socket 套接字传递给 Django 处理。

1. 安装 Nginx

 sudo apt-get install nginx       
 sudo /etc/init.d/nginx start

还有其他的用法Usage: nginx {start|stop|restart|reload|force-reload|status|configtest},后面每次修改站点的 Ngnix 配置文件都需要reload

2. 安装 uWSGI

sudo apt-get install python-dev     
pip install uwsgi

我也不知道前面的 python-dev 是干嘛的,但看别人说要不装就有可能要出错。 还有最后配置文件写在 XML 里面,还要装个 libxml

sudo apt-get install libxml2-dev

3. 测试 Django 应用是否能直接运行并更改为部署配置

整个项目放到服务器上,python manage.py runserver 0.0.0.0:8000,在8000 这个端口上打开试试,运行没有问题就把项目里的settings.py开发配置改成部署配置。

DEBUG = FALSE
ALLOWED_HOSTS = ["*"]

STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)    # 删掉这个配置项

这个地方要把 STATICFILES_DIRS 删掉改成 STATIC_ROOT = "/home/chen/DjangoProjects/static", 然后在执行 python manage.py collectstatic, 这一步会把一些静态文件全复制到项目的静态文件夹下,这个步骤如果不执行的话就会发现部署上去后台是看不到样式的。

4. 测试 uWSGI

在项目下面新建test.py

# test.py
def application(env, start_response):
    start_response('200 OK', [('Content-Type','text/html')])
    return "Hello World"

uwsgi --http :8000 --wsgi-file test.py,在 8000 端口打开试试,能出现 Hello World 就没问题,这个地方由可能回出现一个 libpcrePCRE-8.36 的问题,要自己下回来编译装上就行了。在 Ubuntu 和 Debian 上面也可以直接从仓库安装。

sudo apt-get update 
sudo apt-get install libpcre3 libpcre3-dev
sudo apt-get install openssl libssl-dev

5. my_blog_wsgi.py uWSGI 配置文件

这个地方要是直接照抄各种中文博客到最后肯定都跑不起来,因为他们的 Django 版本太老了,这个地方还是查 stackoverflow 改了就整个跑起来了,Django 1.7 throws django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet

#my_blog_wsgi.py
import os
import sys

reload(sys)
sys.setdefaultencoding('utf8')

from django.core.wsgi import get_wsgi_application    # Django 1.7 前是 from django.core.handlers.wsgi import WSGIHandler

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_blog.settings")    # “你的项目.settings”
application = get_wsgi_application()    # 1.7以前是 application = WSGIHandler()

6. 配置 Nginx

首先由一个文件要复制到项目下面 可以从这里复制粘贴 nginx/conf/uwsgi_params,也可以从 /etc/nginx 里复制过去,可能权限要改下,还是直接自己 vi 粘贴比较好。 第二布是站点的 nginx 配置文件,刚开始我照着别人的做,把这个文件放在自己的项目下,然后软连接上去,结果看 log 说我没有这个文件,然后在放到/etc/nginx/sites-enabled 才行。

# my_blog__nginx.conf

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

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

        # logs  
        access_log /home/chen/DjangoProjects/my_blog/logs/access.log;
        error_log /home/chen/DjangoProjects/my_blog/logs/error.log;

        # Django media
        location /media {
                alias /home/chen/DjangoProjects/my_blog/media; # your Django project's media files - amend as required
        }

        location /static {
            alias /home/chen/DjangoProjects/my_blog/static; # your Django project's static files - amend as required
        }

        # Finally, send all non-media requests to the Django server.
        location / {
                uwsgi_pass  XXX.XXX.XXX:8001;
                include     /home/chen/DjangoProjects/my_blog/uwsgi_params; # the uwsgi_params file you installed   
    }
}

首页就在 8000 这个端口上,server_name 是 VPS 的 IP,logs 文件夹要自己创建,哪都行,/media /static 两个文件夹是静态请求,由 nginx 处理,其他非静态请求由 uwsgi_pass 通过 socket 传递给 Django 处理,用的 8001 端口,include 就是复制的那个文件,放在项目下。

7. my_blog_socket.xml XML 配置文件

<uwsgi>
        <socket>XXX.XXX.XXX.XXX:8001</socket>
        <chdir>/home/chen/DjangoProjects/my_blog</chdir>
        <module>my_blog_wsgi</module>
        <processes>4</processes> 
        <daemonize>/home/chen/DjangoProjects/my_blog/uwsgi.log</daemonize>
</uwsgi>

socket 就是刚才my_blog_bginx.conf 里面的uwsgi_pass通过 Socket 传递过来,chdir 是项目文件夹,modulemy_blog_wsgi.py wsgi 配置文件,processes Nginx 分配四个线程,daemonize 是日志文件,要是配置不成功,错误信息都在里面,什么 libpcre 库没有啊,没有 app load 起来啊。

8. 最后一步

sudo /etc/init.d/nginx reload 
uwsgi -x my_blog_socket.xml

reload 一下 nginx 的配置文件,然后用 xml 配置把 uwsgi 把应用挂起来,提示 [uWSGI] parsing config file my_blog_socket.xml,然后到 ip:8000 端口下看成不成功,不成功的话到项目的uwsgi.log 最后面看,错误信息都在里面,然后去查。

9. 参考链接

基于nginx和uWSGI在Ubuntu上部署Django
五步教你实现使用Nginx+uWSGI+Django方法部署Django程序(上)
五步教你实现使用Nginx+uWSGI+Django方法部署Django程序(下)
Nginx+uWSGI 部署 Django 应用

D
Published on

第二步里的python-dev是一些python的头文件, 编译很多python的library的时候, 是需要头文件的. 还有, 你用apt-get都是sudo, pip为啥不sudo呢?

L
Published on
dxie:

第二步里的python-dev是一些python的头文件, 编译很多python的library的时候, 是需要头文件的. 还有, 你用apt-get都是sudo, pip为啥不sudo呢?

呃……pip 装包应该没啥权限问题吧……

G
Published on
lsdvincent:
dxie:

第二步里的python-dev是一些python的头文件, 编译很多python的library的时候, 是需要头文件的. 还有, 你用apt-get都是sudo, pip为啥不sudo呢?

呃……pip 装包应该没啥权限问题吧……

Python包如果装在系统全局里, 当然一样有环境问题.

你这里能通过, 想必是在virtualenv里面吧, 或者你修改了系统文件夹的权限.

只是你在文章里没有体现出来.

Sign in or Sign up Leave Comment