django部署

     阅读:26

Django部署:Python + ubuntu + Nginx + uWSGI + Django

author:Once Day date:2022年2月13日

本文档在于总结相关内容,零散的知识难以记忆学习。

本文档基于windows平台。

全系列文档查看:Django基础知识_CSDN博客

1.前言

Django 的主要部署的方式是 WSGI,它是 Web 服务器和 Web 应用的 Python 标准,也是所谓的同步服务和默认服务。Django支持:

  • Gunicorn
  • uWSGI
  • Apache
  • Nginx

这里就是选取其中两种Nginx+uWSGI。

用 WSGI 部署的关键是一个叫做application 的可调用对象,应用服务器用它与你的代码交互,是所有请求的接口和入口。我们使用startproject 命令创建项目时会自动创建 /wsgi.py文件,其中就包含了 application 对象,直接使用即可。Django 开发服务器和生产环境的 WSGI 部署都使用它。

WSGI 服务器从其配置文件中获取 application 对象的路径。Django 的开发服务器( runserver ),从配置项 WSGI_APPLICATION 中获取。默认值是 .wsgi.application,指向 /wsgi.py 中的 application

当 WSGI 服务器(uWSGI、Gunicorn等)加载应用时,Django 需要导入配置模块。

Django 利用 DJANGO_SETTINGS_MODULE 环境变量来决定使用哪个settings.py模块,它的值是一个圆点路径字符串。开发环境和生产环境可以配置不同的settings.py。

若未设置该变量, wsgi.py 默认将其设置为 your_site.settingsyour_site 即工程名字。

注意:由于环境变量是进程级的,所以如果在同一进程运行多个 Django 站点将出错。为了避免此问题,可以为每个站点使用 mod_wsgi 的daemon模式。或者在 wsgi.py 中强制设置 os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings" ,重写来自环境变量的值。

2.安装Django

在Ubuntu系统上都自带python,需要注意的是分python2和python3两种,我们用的是python3,这个一定要注意!

使用命令即可:

pip3 install django

但实际上可能有种种问题失败,所以可以参阅文档:初识django。有更多的细节部分!

3.安装Nginx

Ubuntu默认源里面的Nginx版本比较旧,需要先添加一个Nginx的源,再通过apt-get安装Nginx。

sudo add-apt-repository ppa:nginx/stable
apt-get update
apt-get install nginx

Nginx的安装都是比较顺利的!

用ifconfig指令查询本机IP地址并浏览器访问,看到“Welcome to nginx”的字样,则表明安装成功!

如果没有,要注意nginx服务未启动的情况,此时可用

service --status-all

查询,看到nginx前面为+号,即代表服务启动!

......
 [ + ]  network-manager
 [ + ]  networking
 [ + ]  nginx
......

使用以下命令:

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

可以开启、关闭、重启nginx服务!

4.安装uWSGI

uWSGI是实现了WSGI协议的WSGI服务器。是一个快速的、自我驱动的、对开发者和系统管理员友好的应用容器服务器,完全由 C 编写。

uWSGI的官网地址:官网

由于安装过程需要进行C语言编译以及python库函数引用,所以需要额外的软件包支持,请确保一定进行以下步骤,详情可参阅官方安装步骤:Installing uWSGI — uWSGI 2.0 documentation (uwsgi-docs.readthedocs.io)

1.安装 development headers

apt-get install build-essential python3

2.安装 python/wsgi support

apt-get install python3.8-dev

注意这里的python版本一定要和使用的python版本对上,不然后续uWSGI编译会报错!

3.确定是否make可用(gcc,g++可用)

python uwsgiconfig.py --build

4.安装编译uWSGI

# Install the latest stable release:
pip install uwsgi
# ... or if you want to install the latest LTS (long term support) release,
pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz

有两种选择,稳定版本和最新版本,推荐最新版本!也就是第二个!

值得注意的是,uWSGI属于编译后使用,这意味着和python版本是绑定的,甚至和平台也绑定了!

以上步骤结束后,可以尝试运行一下uwsgi,看看是否安装成功!

5.配置uwsgi

先把Django项目上传到服务器里!

在Django项目的根目录下,也就是有manage.py的目录下,新建一个uwsgi.ini文件。文件名可以随便,但后缀必须是ini

如果不清楚Django项目,建议先去学习Django的项目创建!

uwsgi.ini文件写入以下代码:

[uwsgi]
chdir = /..../project
#项目根目录
module = project.wsgi:application
#指定wsgi模块下的application对象
socket = 127.0.0.1:8000
#对本机8000端口提供服务
master = true
#主进程

# 以上4个是核心配置项

#vhost = true          //多站模式
#no-site = true        //多站模式时不设置入口模块和文件
#workers = 2           //子进程数
#reload-mercy = 10
#vacuum = true         //退出、重启时清理文件
#max-requests = 1000
#limit-as = 512
#buffer-size = 30000
#pidfile = /var/run/uwsgi9090.pid    
#pid文件,用于下脚本启动、停止该进程
daemonize = 项目根目录/run.log    
#日志文件
disable-logging = true   
#不记录正常信息,只记录错误信息

详细说明:

  • 配置项中以‘#’开头的都是被注释的项目,不起作用;
  • 以双斜杠开头,表示注释;
  • chdir是你的项目根目录。我这里的项目名叫for_test;
  • moudule是你的入口wsgi模块,将for_test替换成你的项目名称;
  • socket是通信端口设置,和我一样就行;
  • master=True表示以主进程模式运行;
  • demonize是你的日志文件,会自动建立
  • disable-logging = true 表示不记录正常信息,只记录错误信息。否则你的日志可能很快就爆满了。
  • env: 指定DJANGO_SETTINGS_MODULE的值
  • home:可选的项目虚拟环境路径

也可以通过命令参数的方式,不过就显得复杂可不可修改了:

uwsgi --chdir=/path/to/your/project \
    --module=mysite.wsgi:application \
    --env DJANGO_SETTINGS_MODULE=mysite.settings \
    --master --pidfile=/tmp/project-master.pid \
    --socket=127.0.0.1:49152 \      # can also be a file
    --processes=5 \                 # number of worker processes
    --uid=1000 --gid=2000 \         # if root, uwsgi can drop privileges
    --harakiri=20 \                 # respawn processes taking more than 20 seconds
    --max-requests=5000 \           # respawn processes after serving 5000 requests
    --vacuum \                      # clear environment on exit
    --home=/path/to/virtual/env \   # optional path to a virtual environment
    --daemonize=/var/log/uwsgi/yourproject.log      # background the process

6.配置Nginx

备份/etc/nginx/sites-available文件夹内的default文件,然后编辑它(不同的Nginx版本可能配置方法不一样):

##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
server {
    listen 80;
    listen [::]:80;

    # SSL configuration
    #
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self signed certs generated by the ssl-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    # root /var/www/html;

    # Add index.php to the list if you are using PHP
    # index index.html index.htm index.nginx-debian.html;

    server_name 192.168.1.121;
    #服务名填2对外提供服务的地址或域名
    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        # try_files $uri $uri/ =404;
        include  uwsgi_params;
        uwsgi_pass  127.0.0.1:8000;  
    }
    location /static {

    alias /项目根目录/static;
    }
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #   include snippets/fastcgi-php.conf;
    #
    #   # With php7.0-cgi alone:
    #   fastcgi_pass 127.0.0.1:9000;
    #   # With php7.0-fpm:
    #   fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #   deny all;
    #}
}


# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#   listen 80;
#   listen [::]:80;
#
#   server_name example.com;
#
#   root /var/www/example.com;
#   index index.html;
#
#   location / {
#       try_files $uri $uri/ =404;
#   }
#}

关键是这一部分:

server {
    listen 80;

    listen [::]:80;

    server_name 192.168.1.121;

    location / {
        include  uwsgi_params;
        uwsgi_pass  127.0.0.1:8000;  
    }

    location /static {
        alias 项目根目录/static;
    }
}

请将server_name改成你的实际IP。include uwsgi_params一定要一样。uwsgi_pass和你uWSGI配置中的socket要一样。location /static的alias改成你的实际情况,让静态文件得以部署。

修改完毕,保存退出,然后重启nginx服务:

sudo service nginx restart

7.启动服务

下面我们可以尝试启动服务了! 进入项目的根目录,也就是有uwsgi.ini文件的地方,运行:

sudo uwsgi uwsgi.ini

系统提示:

[uWSGI] getting INI configuration from uwsgi.ini

此时访问你的网站页面会显示未得到允许!

进入相应目录,编辑settings.py文件:

DEBUG = False

ALLOWED_HOSTS = ['192.168.1.121']

同时将DEBUG设置为False。如:

Invalid HTTP_HOST header: '192.168.1.121'. You may need to add '192.168.1.121' to ALLOWED_HOSTS.

进入项目的对应目录,编辑settings.py文件:

DEBUG = False

ALLOWED_HOSTS = ['192.168.1.121','www.onceday.work']

这里既可以填域名,也可以填IP地址!

同时将DEBUG设置为False。

在ubuntu中,运行下面的命令:

sudo killall -9 uwsgi

这会删除先前的uWSGI进程。然后等几秒,

sudo uwsgi uwsgi.ini

这是因为端口释放有延迟。

8.注意事项

静态文件是nginx直接分发的,在配置里为,

location /static {
        alias 项目根目录/static;
    }

说明url地址为/static/xxxx/xxx 的匹配到这里,然后换成项目根目录/static/xxxx/xxx,实际上这已经意味着需要把所有的静态文件收集到一起!

但如果不收集的话,则需要在引用静态文件时填上项目根目录到文件的地址,即xxxx/xxx部分,因为你在nginx最多指到某个固定的地址,比如项目根目录下的静态文件夹!

收集静态文件可见:django静态文件部署

推荐参考文档:
注:本文章内容收集总结于互联网,仅供学习之用!