美文网首页技术干货学习漫漫CS之路
基于nginx和uWSGI在Ubuntu上部署Django

基于nginx和uWSGI在Ubuntu上部署Django

作者: Gevin | 来源:发表于2014-09-30 22:04 被阅读40335次

    本文主要参考 uWSGI的文档

    1. nginx

    安装

    sudo apt-get install nginx
    

    启动、停止和重启

    sudo /etc/init.d/nginx start
    sudo /etc/init.d/nginx stop
    sudo /etc/init.d/nginx restart
    

    或者

    sudo service nginx start
    sudo service nginx stop
    sudo service nginx restart
    

    2. uWSGI安装

    用python的pip安装最简单:

    apt-get install python-dev #不安装这个,下面的安装可能会失败
    pip install uwsgi
    

    3. 基于uWSGI和nginx部署Django

    1.原理

    the web client <-> the web server(nginx) <-> the socket <-> uwsgi <-> Django
    

    2.基本测试

    测试uWSGI是否正常

    在django项目的根目录下创建test.py文件,添加源码如下:

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

    然后,Run uWSGI:

    uwsgi --http :8000 --wsgi-file test.py
    

    参数含义:

    • http :8000: 使用http协议,8000端口
    • wsgi-file test.py: 加载指定文件 test.py

    打开下面url,浏览器上应该显示hello world

    http://example.com:8000
    

    如果显示正确,说明下面3个环节是通畅的:

    the web client <-> uWSGI <-> Python
    

    测试Django项目是否正常

    首先确保project本身是正常的:

    python manage.py runserver 0.0.0.0:8000
    

    如果没问题,使用uWSGI把project拉起来:

    uwsgi --http :8000 --module mysite.wsgi
    
    • module mysite.wsgi: 加载wsgi module

    如果project能够正常被拉起,说明以下环节是通的:

    the web client <-> uWSGI <-> Django
    

    3.配置nginx

    安装nginx完成后,如果能正常打开http://hostname,说明下面环节是通畅的:

    the web client <-> the web server
    

    增加nginx配置

    • uwsgi_params文件拷贝到项目文件夹下。uwsgi_params文件在/etc/nginx/目录下,也可以从这个页面下载
    • 在项目文件夹下创建文件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
        }
    }
    

    这个configuration文件告诉nginx从文件系统中拉起media和static文件作为服务,同时相应django的request

    /etc/nginx/sites-enabled目录下创建本文件的连接,使nginx能够使用它:

    sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
    

    部署static文件

    在django的setting文件中,添加下面一行内容:

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

    然后运行:

    python manage.py collectstatic
    

    测试nginx

    首先重启nginx服务:

    sudo /etc/init.d/nginx restart
    

    然后检查media文件是否已经正常拉起:
    在目录/path/to/your/project/project/media directory下添加文件meida.png,然后访问http://example.com:8000/media/media.png ,成功后进行下一步测试。

    4.nginx and uWSGI and test.py

    执行下面代码测试能否让nginx在页面上显示hello, world

    uwsgi --socket :8001 --wsgi-file test.py
    

    访问http://example.com:8000 ,如果显示hello world,则下面环节是否通畅:

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

    用UNIX socket取代TCP port

    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,并在此运行uWSGI

    uwsgi --socket mysite.sock --wsgi-file test.py
    

    打开 http://example.com:8000/ ,看看是否成功

    如果没有成功:

    检查 nginx error log(/var/log/nginx/error.log)。如果错误如下:

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

    添加socket权限再次运行:

    uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666 # (very permissive)
    

    or

    uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664 # (more sensible)
    

    5.Running the Django application with uswgi and nginx

    如果上面一切都显示正常,则下面命令可以拉起django application

    uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=664
    

    Configuring uWSGI to run with a .ini file

    每次都运行上面命令拉起django application实在麻烦,使用.ini文件能简化工作,方法如下:

    在application目录下创建文件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    = 664
    # clear environment on exit
    vacuum          = true
    

    现在,只要执行以下命令,就能够拉起django application:

    uwsgi --ini mysite_uwsgi.ini # the --ini option is used to specify a file
    

    Make uWSGI startup when the system boots

    编辑文件/etc/rc.local, 添加下面内容到这行代码之前exit 0:

    /usr/local/bin/uwsgi --socket /path/to/mysite.sock --module /path/to/mysite.wsgi --chmod-socket=666
    

    uWSGI的更多配置

    env = DJANGO_SETTINGS_MODULE=mysite.settings # set an environment variable
    pidfile = /tmp/project-master.pid # create a pidfile
    harakiri = 20 # respawn processes taking more than 20 seconds
    limit-as = 128 # limit the project to 128 MB
    max-requests = 5000 # respawn processes after serving 5000 requests
    daemonize = /var/log/uwsgi/yourproject.log # background the process & log
    

    相关文章

      网友评论

      • bdef1b31c25a:大神,我用腾讯云的ubuntu服务器,按照这个方法,还是走不通啊,开放的端口是用的:3389,怎么破
      • 和平四季豆:找了好几份文档配置,都没有成功。到这里终于成功了,关键是里面的关键操作都有测试,这个太赞了,谢谢大大
      • f8638f7ffa21:请问http://example.com:8000 中example是什么意思
        谢耳朵_X:示例呀小伙子
      • 6e476438c8eb:mysite.sock这个文件是怎么创建的
      • 熊熊快跑02:最后那句 开机启动的设置不敢用呢?? 还有最后那个uWSGI的更多配置是意思要改还是什么的
        Gevin:@kiv 动动脑子,独立思考 :stuck_out_tongue_closed_eyes:
        kiv:坐等
      • 陈烧面:那个test.py文件要创建在哪里呢
        陈烧面:@SIRENEX 好的~谢谢~
        9facd6554026:Django 项目的根目录,就是你运行manage.py 的那个文件夹。
      • 56e996257c32:前面都正常,在写Nginx的配置文件时,放在工程文件夹下再链接,它怎么也不认,链接路径都正确。后来把它扔到/etc/nginx/sites-available,再链接就好了;
        还有拉图片那块要给media文件夹权限,用sudo chmod 777
        还有给socket权限那里,都是只能用 --chmod-socket=666 ,不能用664,不懂什么意思
        配环境好心塞……
      • 485c5faed2aa:uwsgi --http :8000 --module mysite.wsgi

        假设我的project 叫messi
        如何能确定 mysite.wsgi 就是指向messi这个project里的wsgi.py 呢?
        56e996257c32:命令全写应该是
        uwsgi --http :8000 --chdir /path/to/project --module project.wsgi
        你要是已经cd到project目录下,就不用加chdir了
      • 485c5faed2aa:server unix:///home/www-data/www/mysite/mysite.sock;

        这个mysite.sock本身是不存在的啊... nginx如何调用?
        程序猿tx:@BrucWayne 请问这个.sock文件是如何自动生成的
        485c5faed2aa:OK,不用理我,这个文件是自动生成的...
      • 巴图鲁:厉害
      • Gxpzy:nginx目录下没有sites-enabled,这可咋办 :sweat:
      • 3b12c02062b2:sudo ln -s ~/path/to/your/mysite/mysite_nginx.conf /etc/nginx/sites-enabled/
        这句话略坑,一不留神没看到"~",直接就/root/path/to/your/mysite/mysite_nginx.conf了,检测了很久。。
      • likaiguo:再来一个supervisor配合守护进程就完美了。目前我们项目中是这么做的。
      • 罗西南迪:uwsgi --socket :8001 --wsgi-file test.py 这句执行不成功
        onyourway:@罗西南迪 你的配置或者请求有些方面没有做对吧。
      • 98442bffa4c1:invalid request block size: 21573 (max 4096)...skip
        马面:--socket 换为--http
        罗西南迪:@秦贤康 我也是出现了这个
      • elon:uwsgi --http :8000 --module mysite.wsgi

        这一行不对,应该改成变量形式${yoursite}.wsgi
      • 5c2a9b5a5b2d:真棒,一开始第一步就卡住了,之前操作了pip3 install uwsgi和sudo apt-get install uwsgi,然后就一直 --http命令无效之类的错误提示,然后sudo apt-get remove uwsgi就好了,请问这是为什么? :fearful:
        5c2a9b5a5b2d:@不插电 执行uwsgi --http :8000 --wsgi-file test.py时候报错
      • e14e85a6d30d:@Gevin @apelif @elon 为何我用http的时候,test.py可以跑,用socket就出问题了,
        >uwsgi --socket mysite.sock --wsgi-file test.py
        这个命令返回是400 bad request,
        具体问题我问在这里http://segmentfault.com/q/1010000003021951
        onyourway:权限的问题,vi /var/log/nginx/error.log查看错误日志,这样uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666就能运行了。
        welkinz:我也是这个问题 用http就能拉起项目 用socket就出错
        罗西南迪:@aljun 和你的问题一样
      • Gevin:@elon 是的~ 也适合一个服务器中托管若干不同的网站,而且每个网站依赖不同版本的lib
      • elon:@Gevin 注释掉可以。官方文档有这两行的原因是因为最开始希望在虚拟环境跑吧。
      • Gevin:@elon 我部署的时候virtualenv这两行都写在ini里,但都是注释掉的,拉起网站没问题,你是指把这两行都删掉不写的话就出问题了?
      • elon:@Gevin :smile: 发现了~~~手册里面virtualenv这个最好提一下。因为如果不加的话貌似uwsgi起不来,要不然得在配置里面注释掉才行。
      • Gevin:@elon 没有翻译一遍,官方文档更丰富一点 :stuck_out_tongue_closed_eyes:
      • elon:发现把官方文档翻译了一遍。
      • Gevin:@apelif 自己写一个~ :stuck_out_tongue_winking_eye:
      • apelif:uwsgi --http :8000 --module mysite.wsgi

        django1.4 没有mysite.wsgi文件啊
        485c5faed2aa:这个是自动生成的

      本文标题:基于nginx和uWSGI在Ubuntu上部署Django

      本文链接:https://www.haomeiwen.com/subject/gkgutttx.html