Django -- 部署:nginx+uwsgi+django

相关链接

Django Document

  • Django Document - How to use Django with uWSGI
Static Files:
  • Managing static files (e.g. images, JavaScript, CSS)
  • Deploying static files

nginx document

  • Using NGINX as an Application Gateway with uWSGI and Django

uwsgi document

  • Quickstart for Python/WSGI applications
  • Setting up Django and your web server with uWSGI and nginx -- 强烈推荐

概念

WSGI & uwsgi

WSGI (aka Web Server Gateway Interface)是 Python 定义的标准(PEP333, PEP3333),定义了 Web Server 和 Python Web APP 之间通信的标准

uwsgi 用 C 语言实现了 WSGI 协议

各组件之间的关系

relationship

github - dot language

客户端通过 HTTP协议 向web服务器请求网页,web服务器通过 WSGI协议(或 HTTP协议,socket)与 uwsgi 通信,uwsgi 调用 Python (Django)生成动态网页

为什么需要 WSGI

  • 对于静态文件(HTML, CSS, JS, image)Nginx 可以直接发布
  • 但对于动态生成的网页,Nginx 需要通过 WSGI 向 Django 获取;


    Django -- 部署:nginx+uwsgi+django_第1张图片
    nginx 需要服务两种内容

部署

所需组件

  • Django 项目
  • uwsgi
  • nginx

Django 项目

# mysite/settings.py
import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 项目的根目录
MEDIA_DIR = os.path.join(BASE_DIR, 'media') # 存放 Media 的目录

DEBUG = True

INSTALLED_APPS = [
    'rango',
    # ...
    'django.contrib.staticfiles',
]


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

# Static File 
STATIC_URL = '/static/'

# Media File
MEDIA_ROOT = MEDIA_DIR
MEDIA_URL = '/media/'

为 Media Files 声明 URL

# mysite/urls.py
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path

urlpatterns = [
    # ...
    path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

$ python manage.py runserver

Django -- 部署:nginx+uwsgi+django_第2张图片
HTML, Static Files 可以正常访问
Django -- 部署:nginx+uwsgi+django_第3张图片
Media Files 可以正常访问

在开发阶段,Django runserver 会通过 django.contrib.staticfiles 自动服务位于 app 目录下的 Static 文件和指定目录 Media 文件

nginx

nginx -- 入门

systemctl  status nginx  # 查看状态
systemctl  start nginx.service  # 启动 nginx
systemctl  enable nginx.service  # 开机启动 nginx
Django -- 部署:nginx+uwsgi+django_第4张图片
nginx 欢迎页面 80 端口

nginx 配置文件

在 Django 项目根目录下创建 nginx 配置文件:mysite_nginx.conf
下面以一个项目为例:

  • 项目根目录: /root/django_projects/rango_website/
  • static 文件目录:/www/rango_website/static
  • media 文件目录:/www/rango_website/media
# mysite_nginx.conf

# the upstream component nginx needs to connect to

# nginx 与 uwsgi 通信的地址
upstream django-rango {
    # server unix:///path/to/your/mysite/mysite.sock; # for a file socket
    server 127.0.0.1:8002; # for a web port socket (we'll use this first)
}

# 配置一台 Web Server, 监听 8080 端口
# configuration of the server
server {
    # the port your site will be served on
    listen      8080;
    # the domain name it will serve for
    server_name demo.econfig.cn; # substitute your machine's IP address or FQDN # web Server ip地址或域名
    charset     utf-8;

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

    # 指向 Media Files 目录
    # Django media
    location /media  {
        alias /www/rango_website/media;  # your Django project's media files - amend as required
    }

    # 指向 Static Files 目录
    location /static {
        alias /www/rango_website/static; # your Django project's static files - amend as required
    }

    # 指向 Django 项目
    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django-rango; # 上面 upstream 定义的名字
        include /root/django_projects/rango_website/uwsgi_params; # the uwsgi_params file you installed
    }
}

将 nginx 目录下的 uwsgi_params 复制到 Django项目根目录

$ cp /etc/nginx/uwsgi_params ~/django_projects/rango_website/

创建链接文件:将 Django项目根目录(上面刚刚创建)的 mysite_nginx.conf 链接到 nginx 的配置目录

$ sudo ln -s django_projects/rango_website/django-rango.conf /etc/nginx/conf.d/

让 nginx 重新载入配置文件

$ nginx -s reload 

将 static文件 和 media文件 放到上面指定的目录

# mysite/settings.py    
import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

STATIC_DIR = '/www/rango_website/static'  # static 要存放的目录

# 现在不用告诉 Django : media file 在哪里,因为它交给 nginx 处理
# 但如果还要 运行 Django runserver ,则可以保留
# MEDIA_DIR = os.path.join(BASE_DIR, 'media')


# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ['demo.econfig.cn']


# Application definition

INSTALLED_APPS = [
    'rango',
    # ...
    'django.contrib.staticfiles',


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/



# django 用于生成 static 文件的链接
STATIC_URL = '/static/'
STATIC_ROOT = STATIC_DIR



# 现在不用告诉 Django : media文件 在哪里
# 因为 static文件和 media文件 交给 nginx 去发布
# 但如果还要 运行 Django runserver ,则可以保留

MEDIA_URL = '/media/'
# MEDIA_ROOT = MEDIA_DIR

将 Django 项目 所有app的 static 文件收集到 /www/rango_website/static

$ python manage.py collectstatic
Django -- 部署:nginx+uwsgi+django_第5张图片

手动复制 media 文件

$ cp -r ./media /www/rango_website/

给 static 文件 和 media 文件访问权限

# chmod -R 755 /www

哎,终于好了,static 文件和 media 文件都交给 nginx 发布;人在塔在


Django -- 部署:nginx+uwsgi+django_第6张图片
static 文件可以正常访问

但首页却无法访问,因为动态页面要由 Django 生成,而我们还没启用 uwsgi

Django -- 部署:nginx+uwsgi+django_第7张图片
502 服务器端错误

uwsgi :nginx 和 django 之间的通信媒介

注:这里的 djagno 项目是事先在 pipenv 虚拟环境创建的

$ pipenv install uwsgi  # 安装uwsgi
$ pipenv shell  # 进入 pipenv 虚拟环境

创建 uwsgi 配置文件:mysite_uwsgi.ini

[uwsgi]
socket = :8002 # uswgi 端口
chdir = /root/django_projects/rango_website # django项目根目录
module = rango_website.wsgi  # django项目的 wsgi 模块 rango_website/wsgi.py
processes = 4  # 工作进程数
threads = 2  # 线程数
stats = 127.0.0.1:9002  # 进程统计信息
virtualenv = /root/.local/share/virtualenvs/rango_website-e68KS5mW/  # 虚拟环境位置

# 1个 uwsgi 主进程
# 4个 处理请求的进程
# 每个工作进程有2个线程

啊?我忘记虚拟环境的路径是什么了...

$ pipenv --venv  # 查看虚拟环境路径
/root/.local/share/virtualenvs/rango_website-e68KS5mW

启动 uswgi

$ uwsgi rango_uwsgi.ini
Django -- 部署:nginx+uwsgi+django_第8张图片
uwsgi 启动成功
Django -- 部署:nginx+uwsgi+django_第9张图片
访问首页
relationship
Django -- 部署:nginx+uwsgi+django_第10张图片

Django -- 部署:nginx+uwsgi+django_第11张图片

错误

访问 static 文件和 media 文件 出现 404 错误

反问三连
  • nginx 配置文件中 static 文件和 media文件 的路径正确吗
Django -- 部署:nginx+uwsgi+django_第12张图片
mysite_nginx.conf
  • 重新载入 nginx 配置文件了吗 nginx -s reload

  • static 文件 和 media 文件放到 指定目录了吗

$ python manage.py collectstatic
$ cp -r ./media /www/rango_website/

访问 static 文件和 media 文件 出现 403 错误 (拒绝访问)

目录权限给了吗 # chmod -R 755 /www

你可能感兴趣的:(Django -- 部署:nginx+uwsgi+django)