使用runserver可以使我们的django项目很便捷的在本地运行起来,但这只能在局域网内访问,如果在生产环境部署django,就要多考虑一些问题了。比如静态文件处理,安全,效率等等,本篇文章总结归纳了一下基于uwsgi+Nginx下django项目生产环境的部署

    准备条件:

    linux上已部署好python环境,且已安装好项目所需的模块

    安装python环境,请参考以下链接

    http://www.py3study.com/Article/details/id/320.html

    创建django项目

    [root@localhost ~]# cd /www/
    [root@localhost www]# django-admin startproject mysite1
    [root@localhost www]# cd mysite1
    [root@localhost mysite1]# python manage.py startapp blog
    [root@localhost mysite1]# mkdir static
    #编辑配置文件
    [root@localhost mysite1]# vim mysite1/settings.py
    #允许所有IP,注意:'*'必须用引号包起来
    ALLOWED_HOSTS = ['*']

    如果提示-bash: django-admin: 未找到命令

    请使用命令pip3 install django 安装

    启动项目,监听本机所有IP的8001端口

    [root@localhost mysite1]# python manage.py runserver 0.0.0.0:8001
    Performing system checks...
    System check identified no issues (0 silenced).
    You have 14 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
    Run 'python manage.py migrate' to apply them.
    June 24, 2018 - 03:48:20
    Django version 2.0.6, using settings 'mysite1.settings'
    Starting development server at http://0.0.0.0:8001/
    Quit the server with CONTROL-C.

    访问页面:

    http://192.168.11.103:8001/

    出现下面的网页,说明成功了。

    安装uwsgi

    uwsgi是python的一个模块,安装uwsgi只需简单的pip命令就可以了

    pip3 install uwsgi

    如果提示:

    You should consider upgrading via the 'pip install --upgrade pip' command.

    使用命令:pip3 install --upgrade pip 进行升级

    基于uwsgi+django的实现

    1.使用命令启动uwsgi

    先关闭上面启动的Django项目,使用Ctrl+c,就可以取消。

    第一步:进入django项目

    cd /www/mysite1/

    第二步:命令测试启动

    uwsgi --http 0.0.0.0:8080 --file mysite1/wsgi.py --static-map=/static=static

    参数说明:

    --http 这个就和runserver一样指定IP 端口

    --file 这个文件就里有一个反射,如果你在调用他的时候没有指定Web Server就使用默认的

    注意:mysite1是一个相对路径。--file它的绝对路径是/www/mysite1/mysite1/wsgi.py

    --static 做一个映射,指定静态文件。

    此时,访问http://192.168.11.103:8080/

    如图所示,表示项目启动成功

    2.使用uwsgi配置文件启动django项目

    使用Ctrl+c,取消uwsgi启动。

    第一步:在django项目同级目录创建script目录,用于存放配置脚本等等

    mkdir script

    项目结构如下:

    mysite1/
    ├── blog
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── tests.py
    │   └── views.py
    ├── db.sqlite3
    ├── manage.py
    ├── mysite1
    │   ├── __init__.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── script
    └── static

    第二步:进入script目录,创建一个uwsgi.ini文件

    cd script

    vim uwsgi.ini

    编辑uwsgi.ini文件内容如下:

    # uwsig使用配置文件启动
    [uwsgi]
    # 项目目录
    chdir=/www/mysite1/
    # 指定项目的application
    module=mysite1.mysite1.wsgi:application
    # 指定sock的文件路径
    socket=/www/mysite1/mysite1.sock
    # 进程个数
    workers=5
    pidfile=/www/mysite1/script/uwsgi.pid
    # 指定IP端口
    http=0.0.0.0:8001
    # 指定静态文件
    static-map=/static=/www/mysite1/static
    # 启动uwsgi的用户名和用户组
    uid=root
    gid=root
    # 启用主进程
    master=true
    # 自动移除unix Socket和pid文件当服务停止的时候
    vacuum=true
    # 序列化接受的内容,如果可能的话
    thunder-lock=true
    # 启用线程
    enable-threads=true
    # 设置自中断时间
    harakiri=30
    # 设置缓冲
    post-buffering=8192
    # 设置日志目录
    daemonize=/www/mysite1/script/uwsgi.log
    wsgi-file = /www/mysite1/mysite1/wsgi.py

    注意:

    chdir的目录要正确,目录后面要加斜杠

    module的配置,要特别小心

    mysite1.mysite1.wsgi这一句表示mysite1项目下的mysite1目录下的wsgi.py文件。

    很多教程都是这样写的mysite1.wsgi:application

    那是因为他们直接将uwsgi.ini放到和manage.py在同一级目录。

    但是我创建了script目录,需要将uwsgi.ini放到script目录。所以路径必须多加一层才行!

    启动项目:

    注意:必须切换到script目录

    cd /www/mysite1/script

    uwsgi --ini uwsgi.ini

    它会输出如下信息:

    [uWSGI] getting INI configuration from uwsgi.ini
    [uwsgi-static] added mapping for /static => /www/mysite1/static

    如果需要关闭项目,使用命令:

    cd /www/mysite1/script

    uwsgi --stop uwsgi.pid

    这里,先不要执行关闭命令。

    访问http://192.168.11.103:8001/

    因为uwsgi定义的端口是8001。如图所示,表示项目启动成功

    如果出现(HTTP/1.1 500) 错误,请仔细检查

    chdir,module,socket,wsgi-file 这几项配置是否正确!

    安装tengine

    说到tengine,首先还是得说下nginx了,大家对于nginx并不陌生,对于基本的需求都能满足,如果是涉及高级性能,那么就必须使用商用版nginx plus了,一谈到商用,大家就特别敏感,有没有开源免费的呢,有的,所以tengine诞生了。

    Tengine(http://tengine.taobao.org/index_cn.html)是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。主要特性,请查看官网:

    http://tengine.taobao.org/

    从官网下载最新版本。目前最新稳定版本是2.2.2,下载链接为:

    http://tengine.taobao.org/download/tengine-2.2.2.tar.gz

    安装依赖包

    yum install -y gcc gcc-c++ autoconf automake pcre pcre-devel openssl openssl-devel

    解压安装

    tar zxvf tengine-2.2.2.tar.gz -C /usr/src/

    cd /usr/src/tengine-2.2.2/

    ./configure --prefix=/usr/local/tengine --with-http_sub_module --with-http_stub_status_module --with-http_gzip_static_module

    make && make install

    新建用户和组

    groupadd www

    useradd -g www -s /sbin/nologin www

    进入tengine目录,备份配置文件,编辑配置文件

    cd /usr/local/tengine/conf

    mv nginx.conf nginx.conf.bak

    vim nginx.conf

    完整内容如下:

    user  www www;
    worker_processes  4;  # cpu核心数 error_log  logs/error.log;

    #error_log  logs/error.log  notice;

    #error_log  logs/error.log  info; pid        logs/nginx.pid; events {

        worker_connections  60240;

    #接受尽可能多的连接

        multi_accept on;

    #网络I/O模型

        use epoll;

    } #进程打开的最多文件描述符数目

    worker_rlimit_nofile 65535; http {

        include       mime.types;

        default_type  application/octet-stream;     #隐藏版本号

        server_tokens off;

        keepalive_timeout 30;

        sendfile on;

        tcp_nopush on;

        tcp_nodelay on;

        gzip on;

        gzip_min_length 1000;

        gzip_comp_level 9;

        gzip_proxied any;

        gzip_types text/plain text/css text/xml

                   application/x-javascript application/xml

                   application/atom+xml text/javascript

           application/x-httpd-php image/jpeg

           image/gif image/png;     #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

        #                  '$status $body_bytes_sent "$http_referer" '

        #                  '"$http_user_agent" "$http_x_forwarded_for"';

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                          '$status $body_bytes_sent "$http_referer" '

                          '"$http_user_agent" "$http_x_forwarded_for"'

                           '$upstream_response_time $request_time ';     access_log  logs/access.log  main;

        #缓存打开的文件描述符

        open_file_cache max=100000 inactive=20s;

        #多长时间检查一次缓存的有效信息

        open_file_cache_valid 30s;

        #open_file_cache指令中的inactive参数时间内文件的最少使用次数

        open_file_cache_min_uses 2;

        #指定是否在搜索一个文件是记录cache错误

        open_file_cache_errors on;     #允许客户端请求的最大单文件字节数

        client_max_body_size 64M;

        #缓冲区代理缓冲用户端请求的最大字节数

        client_body_buffer_size  432K;

        #设定请求缓冲

        client_header_buffer_size 16k;

        #指定客户端的响应超时时间

        send_timeout 60;

        #可通过keep-alive连接的客户端请求数

        keepalive_requests 100000;

        large_client_header_buffers 4 64k;

        proxy_connect_timeout 300s;

        proxy_read_timeout 300s;

        proxy_send_timeout 300s;

        proxy_buffer_size 128k;

        proxy_buffers 32 32k;

        proxy_busy_buffers_size 128k;

        proxy_temp_file_write_size 128k;

        proxy_ignore_client_abort on;     server_names_hash_bucket_size 512;     #虚拟主机配置文件目录

        include vhosts/*; }

    创建虚拟目录

    mkdir vhosts

    cd vhosts/

    编辑配置文件mysite.conf

    vim mysite.conf

    内容如下:

    server {

        listen 80;

        server_name localhost;     # 指定项目路径uwsgi

        location / {

            include uwsgi_params; # 导入一个Nginx模块他是用来和uWSGI进行通讯的

            uwsgi_connect_timeout 30; # 设置连接uWSGI超时时间

            uwsgi_pass unix:/www/mysite1/mysite1.sock; # 指定uwsgi的sock文件所有动态请求就会直接丢给他

        }     # 指定静态文件路径

        location /static/ {

            alias /www/mysite1/static/;

        } }

    判断配置文件是否有错误,并启动nginx

    [root@localhost vhosts]# ../../sbin/nginx -t

    nginx: the configuration file /usr/local/tengine/conf/nginx.conf syntax is ok

    nginx: configuration file /usr/local/tengine/conf/nginx.conf test is successful

    [root@localhost vhosts]# ../../sbin/nginx

    访问首页,直接IP访问即可。

    http://192.168.11.103/

    出现以下页面,说明成功了!

    进入/www/mysite1/static/目录,创建3个目录

    cd /www/mysite1/static/

    mkdir css

    mkdir js

    mkdir images

    上传一个图片到images目录

    网页访问图片

    http://192.168.11.103/static/images/zly.jpg

    测试一下,表单提交

    因为这里还没有数据库,直接使用写入文件方式来存储数据。

    准备静态文件

    下载Bootstrap,官方网址为:

    http://www.bootcss.com/

    下载最新稳定版本3.3.7,选择用于生产环境的

    https://v3.bootcss.com/getting-started/#download

    将压缩包里面的bootstrap.min.css放到css目录

    bootstrap.min.js放到js目录

    下载jquery:

    https://code.jquery.com/jquery-3.3.1.min.js

    将jquery-3.3.1.min.js放到js目录

    修改django相关文件

    修改urls.py,增加路径userInfo 

    vim /www/mysite1/mysite1/urls.py

    from django.contrib import admin

    from django.urls import path

    from blog import views urlpatterns = [

        path('admin/', admin.site.urls),

        path('userInfo/', views.userInfo),

    ]

    修改views.py,增加视图函数userInfo

    vim /www/mysite1/blog/views.py

    from django.shortcuts import render,HttpResponse

    import os

    import json # Create your views here. def userInfo(req):

        filename = 'userInfo.txt'

        #判断请求类型

        if req.method == "POST":

            #获取表单数据,如果获取不到,则为None

            username = req.POST.get("username",None)

            password = req.POST.get("password", None)

            email = req.POST.get("email", None)

            # print(username,password,email)

            #定义字典

            user = {'username':username,'password':password,'email':email}

            #追加到列表中

            f = open(filename, 'a', encoding='utf-8')

            f.write(json.dumps(user) + '\n')     # 判断认证文件是否存在,否则自动创建

        if os.path.exists(filename) == False:

            with open(filename, encoding='utf-8', mode='w') as mk:

                #写入默认数据

                # default =

                mk.write(json.dumps({'username':'xiao','password':'123','email':'123@qq.com'})+'\n')     #读取文件数据

        f = open(filename, 'r', encoding='utf-8')

        user_list = []  # 定义空列表

        for i in f:

            # print(json.loads(i.strip()))

            user_list.append(json.loads(i.strip()))

        f.close()

        # 将列表传给模板index.html

        return render(req, "index.html", {"user_list": user_list})

    创建目录templates

    cd /www/mysite1

    mkdir templates

    修改index.html文件

    vim /www/mysite1/templates/index.html

    内容如下:

    <!DOCTYPE html>

    <html lang="en">

    <head>

        <meta charset="UTF-8">

        <!--告诉IE使用最新的引擎渲染网页,chrome=1则可以激活Chrome Frame-->

     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>

        <!--适用于移动设备,禁止页面缩放-->

     <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Bootstrap -->

     <script src='/static/js/jquery-3.3.1.min.js'></script>

        <link href="/static/css/bootstrap.min.css" rel="stylesheet">

        <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->

     <script src="/static/js/bootstrap.min.js"></script>     <title>Title</title>

        <style>

            .col-center-block {

                float: none;

     display: block;

     margin-left: auto;

     margin-right: auto;

     }     </style>

    </head>

    <body> <!--正文-->

    <div class="container">

        <div class="row">

            <div class="col-md-6 col-center-block">

                <!--面板-->

                <!--panel-success显示绿色-->

     <div class="panel panel-success">

                    <div class="panel-heading">

                        <h3 class="panel-title text-center">注册</h3>

                    </div>

                    <div class="panel-body">

                        <form class="form-horizontal" action="/userInfo/" method="post">

                            <div class="form-group">

                                <label for="inputUser1" class="col-sm-2 control-label">用户名</label>

                                <div class="col-sm-10">

                                    <input type="text" name="username" class="form-control" id="inputUser1"

     placeholder="请输入用户名">

                                </div>

                            </div>

                            <div class="form-group">

                                <label for="inputPassword1" class="col-sm-2 control-label">密码</label>

                                <div class="col-sm-10">

                                    <input type="password" name="password" class="form-control" id="inputPassword1"

     placeholder="请输入密码">

                                </div>

                            </div>

                            <div class="form-group">

                                <label for="inputEmail3" class="col-sm-2 control-label">邮箱</label>

                                <div class="col-sm-10">

                                    <input type="email" name="email" class="form-control" id="inputEmail3"

     placeholder="请输入邮箱">

                                </div>

                            </div>

                            <div class="form-group">

                                <div class="col-sm-offset-2 col-sm-10">

                                    <button type="submit" class="btn btn-success text-left">注册</button>                             </div>

                            </div>

                        </form>                     {#判断列表有数据的情况下#}

                        {% if user_list %}

     <hr/>

                        <h2>数据展示</h2>

                        <!--面板-->

     <div class="panel panel-default">

                            <div class="panel-heading">

                                <h3 class="panel-title">标签</h3>

                            </div>

                            <div class="panel-body">

                                <table class="table table-striped table-bordered table-hover table-condensed">

                                    <thead>

                                    <tr>

                                        <th>姓名</th>

                                        <th>密码</th>

                                        <th>邮箱</th>

                                    </tr>

                                    </thead>

                                    <tbody>

                                    {#使用for循环遍历列表#}

                                    {% for i in user_list %}

     <tr>

                                        {#展示数据#}

     <td>{{i.username}}</td>

                                        <td>{{i.password}}</td>

                                        <td>{{i.email}}</td>

                                    </tr>

                                    {#结束for循环#}

                                    {% endfor %}  </tbody>

                                </table>

                            </div>

                        </div>

                        {#一定要写结束符#}

                        {% endif %}  </div>

                </div>         </div>

        </div>

    </div> </body>

    </html>

    修改settings.py

    vim /www/mysite1/mysite1/settings.py

    关闭CSRF

    MIDDLEWARE = [

        'django.middleware.security.SecurityMiddleware',

        'django.contrib.sessions.middleware.SessionMiddleware',

        'django.middleware.common.CommonMiddleware',

        #'django.middleware.csrf.CsrfViewMiddleware',

        'django.contrib.auth.middleware.AuthenticationMiddleware',

        'django.contrib.messages.middleware.MessageMiddleware',

        'django.middleware.clickjacking.XFrameOptionsMiddleware',

    ]

    定义templates目录

    TEMPLATES = [

        {

            'BACKEND': 'django.template.backends.django.DjangoTemplates',

            'DIRS': [os.path.join(BASE_DIR, 'templates')],

            'APP_DIRS': True,

            'OPTIONS': {

                'context_processors': [

                    'django.template.context_processors.debug',

                    'django.template.context_processors.request',

                    'django.contrib.auth.context_processors.auth',

                    'django.contrib.messages.context_processors.messages',

                ],

            },

        },

    ]

    定义static目录

    STATIC_URL = '/static/'

    STATICFILES_DIRS = (

        os.path.join(BASE_DIR,"static"),

    )

    项目解构如下:

    mysite1/

    ├── blog

    │   ├── admin.py

    │   ├── apps.py

    │   ├── init.py

    │   ├── migrations

    │   │   └── init.py

    │   ├── models.py

    │   ├── tests.py

    │   └── views.py

    ├── db.sqlite3

    ├── manage.py

    ├── mysite1

    │   ├── init.py

    │   ├── settings.py

    │   ├── urls.py

    │   └── wsgi.py

    ├── mysite1.sock

    ├── script

    │   ├── uwsgi.ini

    │   ├── uwsgi.log

    │   └── uwsgi.pid

    ├── static

    │   ├── css

    │   │   └── bootstrap.min.css

    │   ├── images

    │   │   └── zly.jpg

    │   └── js

    │       ├── bootstrap.min.js

    │       └── jquery-3.3.1.min.js

    └── templates

        └── index.html

    关闭uwsgi

    cd /www/mysite1/script

    uwsgi --stop uwsgi.pid

    启动uwsgi

    uwsgi --ini uwsgi.ini

    访问网页:

    http://192.168.11.103/userInfo/

    默认有一条数据

    添加2条数据

    最终效果如下:

Django + Uwsgi + Nginx 的生产环境部署的更多相关文章

  1. 10: Django + Uwsgi + Nginx 的生产环境部署

    1.1 一些重要概念 1.Web协议介绍 Web协议出现顺序: CGI -> FCGI -> WSGI -> uwsgi 1. CGI:  最早的协议 2. FCGI:  比CGI快 ...

  2. Django + Uwsgi + Nginx 的生产环境部署实战

    目录 Django + Uwsgi + Nginx 的生产环境部署实战 安装Uwsgi 一.使用命令来启动django项目 二.使用配置文件来启动我们的Django项目 安装Nginx 配置Nginx ...

  3. ubuntu Django + Uwsgi + Nginx 的生产环境部署

    一.概述 使用runserver可以使我们的django项目很便捷的在本地运行起来,但这只能在局域网内访问,如果在生产环境部署django,就要多考虑一些问题了.比如静态文件处理,安全,效率等等,本篇 ...

  4. Django + Uwsgi + Nginx 实现生产环境部署

    本节内容 uwsgi 介绍 uwsgi安装使用 nginx安装配置 django with nginx 如何在生产上部署Django? Django的部署可以有很多方式,采用nginx+uwsgi的方 ...

  5. 11: Django + gunicorn + Nginx 的生产环境部署

    1.1 gunicorn介绍   1.Gunicorn 1. Gunicorn是使用Python实现的WSGI服务器, 直接提供了http服务, 并且在woker上提供了多种选择, gevent, e ...

  6. Django + Uwsgi + Nginx 实现生产环境 项目部署

    内容: uwsgi 介绍 uwsgi安装使用 nginx安装配置 django with nginx 如何在生产上部署Django项目? Django项目的部署可以有很多方式,采用nginx+uwsg ...

  7. Django+uwsgi+nginx+angular.js项目部署

    这次部署的前后端分离的项目: 前端采用angular.js,后端采用Django(restframework),他俩之间主要以json数据作为交互 Django+uwsgi的配置可以参考我之前的博客: ...

  8. django+nginx+python3 生产环境部署

    一.安装python基础环境 1.安装各类基础模块 yum install  gcc-c++ wget openssl-devel bzip2-devel expat-devel gdbm-devel ...

  9. CentOs Linux 对于Django uwsgi + Nginx 的安装与部署

    Django Nginx+uWSGI 安装配置 链接:

随机推荐

  1. C# Note37: Writing unit tests with use of mocking

    前言 What's mocking and its benefits Mocking is an integral part of unit testing. Although you can run ...

  2. 洛谷P3957 跳房子(Noip2017普及组 T4)

    今天我们的考试就考到了这道题,在考场上就压根没有思路,我知道它是一道dp的题,但因为太弱还是写不出来. 下来评讲的时候知道了一些思路,是dp加上二分查找的方式,还能够用单调队列优化. 但看了网上的许多 ...

  3. UIAutomator简介

    简介 Android 4.3发布的时候包含了一种新的测试工具–uiautomator,uiautomator是用来做UI测试的.也就是普通的手工测试,点击每个控件元素 看看输出的结果是否符合预期.比如 ...

  4. [模板] 次短路 | bzoj1726-[Usaco2006Nov]Roadblocks第二短路

    简介 所谓次短路, 顾名思义, 就是第二短路. :P 1到n的次短路长度必然产生于:1到x的最短路 + edge(x,y) + y到n的最短路 简单证明一下: 设 \(dis(i,j)\) 表示 \( ...

  5. Java大小写转化

    java大写转小写 public String toLowerCase(String str){ char[] chars = str.toCharArray(); for (int i = 0; i ...

  6. 洛谷P1072 Hankson 的趣味题(题解)

    https://www.luogu.org/problemnew/show/P1072(题目传送) 数学的推理在编程的体现越来越明显了.(本人嘀咕) 首先,我们知道这两个等式: (a0,x)=a1,[ ...

  7. springboot中关闭eureka server中已注册服务列表自我保护配置

    配置集群服务可以向eureka通知应用是否可以使用a.在eureka server的application.properties中加入:# 设为false,关闭自我保护eureka.server.en ...

  8. 二.django项目环境搭建

    Ⅰ.web框架介绍 1.socket 服务端 1)客户端(手机中各种app.浏览器)是用来与服务端(网站的服务器程序)进行交互的 2)服务端类似发电厂,客户端类似电器,socket类似插座,互联网的数 ...

  9. 深入学习c++(虚函数遇到析构函数就退化了)

    1. 在构造函数和析构函数中调用的虚函数并不具备虚函数的特性 因为基类的构造函数先构造, 析构函数后析构

  10. Run Configurations(Debug Configurations)->Arguments里填写program arguments和VM arguments

    如图: 1.program arguments存储在String[] args里 2.VM arguments设置的是虚拟机的属性,是传给java虚拟机的.KV形式存储的,是可以通过System.ge ...