一文彻底弄通django项目生产环境配置,并部署到阿里云服务器

7 篇文章 0 订阅
3 篇文章 0 订阅

django项目部署

settings中的首先要确保这两项修改过来:

DEBUG = False#防止一些数据或者敏感数据被泄漏

ALLOWED_HOSTS = ['*']#保证每个人都能访问

需要上传django项目文件,重建虚拟的python环境

  • pip3.6 install virtualenv
  • virtualenv --python=/usr/bin/python3.6 /home/loverweb/venv
  • source /home/loverweb/venv/bin/activate

参考:https://blog.csdn.net/duxin_csdn/article/details/83341922

关于之前项目开发使用的库,可以构建requirements.txt文件,然后在服务器商直接通过 pip install -r requirements.txt,进行快速的下载

配置好静态文件和媒体文件

注意,要配置好静态文件和媒体文件的ROOT路径,不然nginx会出错,如ngnix的error.log有一条报错:

2020/11/11 17:32:04 [error] 24872#24872: *60 open() "/home/Django/static/rest_framework/js/default.js" failed (2: No such file or directory), client: 111.42.148.86, server: www.XXX.fun, request: "GET /static/rest_framework/js/default.js HTTP/1.1", host: "www.XXX.fun", referrer: "http://www.XXXX.fun/goods/get_classes/"

配置静态文件步骤如下

  • 首先要保证settings中的INSTALLED_APPS中有django.contrib.staticfiles。当settings中的DEBUG=True时,django会自动的处理。这种方法效率比较低,且不安全,只有在开发中才使用。而我们在生产环境中DEBUG一般是False。

  • settings中定义静态文件的URL:STATIC_URL = ‘/static/’

  • 也可以设定额外的静态文件夹,django会自动的搜索

      STATICFILES_DIRS = [
      BASE_DIR / "static",
      '/var/www/static/',
      ]
    
  • 还需要在settings中配置STATIC_ROOT,这里需要是绝对的路径,如

      STATIC_ROOT='/home/Django/static'
    

当然更好是进行这样的设定,利用base路径,更灵活:

	STATIC_ROOT = os.path.join(BASE_DIR, 'static')

或者
STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), ‘static’)

  • 进行静态文件的收集,这一步必须操作,因为我们用的python库,它会有js等静态文件,这会将库用的一些js静态文件迁移到这里。

      python3 manage.py collectstatic
    
  • 另外最好给static文件夹提升权限:

      sudo chmod 777 static
    

静态文件配置完成。而媒体文件配置比较简单,我们在settings中加入:

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

保险点的,我们可以在settings同级的urls.py中url列表,加入:

#媒体文件夹
re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}),

因为,我们后面会用Nginx直接访问媒体文件,所以我认为这个url配置是多余的。但是没有尝试,去掉后,媒体文件访问是否正常。

官网的参考:

django生产环境搭建原理###

配置django的生产环境就是利用nginx+uwsgi+django.而实现Nginx与uWSGI的连接,两者之间将采用soket来通讯方式

名词

https://www.cnblogs.com/gaosai/p/10319605.html

  • nginx:Web服务器和作为反向代理服务器:用来做负载均衡。比如静态文件处理,安全,效率等等。

    正向代理:

    我访问不了某网站比如www.google.com,但是我能访问一个代理服务器,这个代理服务器呢,它能访问那个我不能访问的网站,于是我先连上代理服务器,告诉它我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。

    反向代理

    当我们请求 www.baidu.com 的时候,当我们访问www.baidu.com的时候,背后可能有成千上万台服务器为我们服务,但具体是哪一台,不知道,也不需要知道,只需要知道反向代理服务器是谁就好了,www.baidu.com 就是我们的反向代理服务器,反向代理服务器会帮我们把请求转发到真实的服务器那里去。

  • WSGI:Web Server Gateway Interface,就是一个网关,用来在协议之间进行转换。比如作为nginx和uWSGI的通讯协议。在python实际的生产环境中,WSGI经常被使用。WSGI没有官方的实现, 因为WSGI更像一个协议,只要遵照这些协议,WSGI应用(Application)都可以在任何服务器(Server)上运行。

  • uWSGI:应用服务器:它实现了 WSGI 协议、uwsgi、http 等协议。Nginx 中HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换。Nginx 中HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换。

上文所述的uWSGI 实现了WSGI的所有接口,是一个快速、自我修复、开发人员和系统管理员友好的服务器。把 HTTP 协议转化成语言支持的网络协议。uWSGI代码完全用C编写,效率高、性能稳定。

  • uwsgi(全小写): 和uWSGI 不一样,uwsgi是一种线路协议,不是通信协议,常用于在uWSGI服务器与其他网络服务器的数据通信。uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型。

注意 WSGI / uwsgi / uWSGI 这三个概念的区分:WSGI 是一种通信协议。uwsgi 是一种线路协议而不是通信协议,在此常用于在 uWSGI 服务器与其他网络服务器的数据通uWSGI 是实现了 uwsgi 和 WSGI 两种协议的 Web 服务器。

参考:https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html

配置django的生产环境就是利用nginx+uwsgi+django.而实现Nginx与uWSGI的连接,两者之间将采用soket来通讯方式

django生产环境的访问流程
  1. 首先浏览器发起 http 请求到 nginx 服务器,Nginx 根据接收到请求包,进行 url 分析,判断访问的资源类型,

  2. 如果是静态资源,直接读取静态资源返回给浏览器,如果请求的是动态资源就转交给 uwsgi服务器

  3. uwsgi 服务器根据自身的 uwsgi 和 WSGI 协议,找到对应的 Django 框架Django 框架下的应用进行逻辑处理后,将返回值发送到 uwsgi 服务器

  4. 然后 uwsgi 服务器再返回给 nginx,最后 nginx将返回值返回给浏览器进行渲染显示给用户

uwsgi的官方说明:https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html

服务器架构:

django的uwsgi和nginx的配置

知道了原理后,我们进行uwsgi和nginx配置,才会明白每一项的含义。

uwsgi的配置

参考:https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html

简单熟悉uwsgi的用法和作用

我们先建立一个简单的python应用foobar.py:
#定义应用的意思是这是uWSGI的默认的python加载器,uWGSI能够自动搜索到
def application(env, start_response):
start_response(‘200 OK’, [(‘Content-Type’,‘text/html’)])
return [b"Hello World"]

然后我们使用以下命令:

uwsgi --http :9090 --wsgi-file foobar.py

然后我们可以给其增加进程和线程:

uwsgi --http :9090 --wsgi-file foobar.py --master --processes 4 --threads 2

当然我们也可以挂载django项目,假设django项目在/home/foobar/myproject:

uwsgi --socket 127.0.0.1:3031 --chdir /home/foobar/myproject/ --wsgi-file myproject/wsgi.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

从上面可以看到命令太长,当然了我们可以设定一个配置文件,来启动django项目,所以这就是uWGSI配置文件,以及我们需要配置文件.ini的原因了,上面的可以配置uswgifile.ini一般与与manage.py在同一级目录
[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
wsgi-file = myproject/wsgi.py
processes = 4
threads = 2
stats = 127.0.0.1:9191

然后,就可以直接运行: uwsgi yourfile.ini

可以看到,上面有一个wsgi-file文件,这个django1.4以后的版本,在创建项目的时候都会自动生成,在跟settings.py同级的文件下,如上面的项目是在/home/foobar/myproject/myproject/wsgi.py。如果没有这个wsgi.py,可以配置如下:

[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
pythonpath = ..
env = DJANGO_SETTINGS_MODULE=myproject.settings
module = django.core.handlers.wsgi:WSGIHandler()
processes = 4
threads = 2
stats = 127.0.0.1:9191
django生产环境的uwsgi配置示例

从上面的例子,我们知道,uwsgi无非就是写个配置文件,启动就行,一般生产环境用的uwsgi如下:

[uwsgi]

# Django-related settings
# the base directory (full path)
chdir           = /home/Django/
# Django's wsgi file,django2.0会自动生成一wsgi文件,在settings统计的目录下
module          = Django.wsgi
# the virtualenv (full path)
home            = /home/IHIT/Django/venv
#如果找不到django等模块的错误,可以尝试加这个参数
#pythonpath=/home/Django/venv/lib/python3.6/site-packages
# process-related settings
# master
master          = true#以主近程模式运行

# maximum number of worker processes,一般为cpu的核心数
processes       = 4
#两个线程
threads=2
# 存放进程编号的文件,这个pid文件可以用来快速的停止uwsgi。
pidfile= /home/IHIT/Django/uwsgi.pid
# the socket (use the full path to be safe,这个是套接字文件,表示Unix套接字.在这种情况下,uWSGI会创建它,并且将通过此套接字uWSGI和Nginx将彼此通信.)
socket          = /home/IHIT/Django/mysite.sock
# ... with appropriate permissions - may be needed,这个是权限设置,如果把permission error 13,就需要加上这个权限设置,666这个权限的意思跟linux文件夹的权限是一样的。
chmod-socket    = 666
# clear environment on exit
vacuum          = true

# 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的
daemonize=/home/IHIT/Django/logs/uwsgi/uwsgi.log

# 仅记录错误信息,减少日志文件的体积

disable-logging = true 

uswgi的参数配置很多,我们可以参考下面的说明:

uwsgi基础使用命令:启动。停止,重启
  • 启动:

    uwsgi --ini xxx.ini

  • 重启:

    uwsgi --reload xxx.pid

  • 停止:

    uwsgi --stop xxx.pid

如果不知道pid号,可以是用 ps aux |grep uwsgi查看,然后进行kill

配置uwgsi遇见的问题:####
  • 配置uwgsi时,出现找不到django模块的错误:如

      Traceback (most recent call last):
        File "./Django/wsgi.py", line 12, in <module>
          from django.core.wsgi import get_wsgi_application
      ModuleNotFoundError: No module named 'django'
      unable to load app 0 (mountpoint='') (callable not found or import error)
      *** no app loaded. going in full dynamic mode ***
    

    这个问题一般是没有配置好python虚拟环境在的位置,重新配置home参量所对的python虚拟环境的路径。如果还不行,在uwgsi中,可以用以下的命令看看django在哪个位置:

      pip show django|grep -i location
    

    结果是一个路径:

      Location: /usr/local/lib64/python3.6/site-packages
    

    把这个路径加在uwgsi文件中:

      pythonpath=/usr/local/lib64/python3.6/site-packages
    

配置nginx

nginx的简单说明####

与uwsgi一样的, nginx也是写好配置文件,运行即可。

为了实现Nginx与uWSGI的连接,两者之间将采用soket来通讯方式(上文介绍过).Nginx一般采用8077端口与uWSGI通讯.一般可以通过端口进行通信,如在nginx配置文件中有:

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

注:这个location其实就相当于你在开发django时的url。 如果明白这个,那对nginx的反向代理应该就能理解了。(理解这个,我们我们也就能对同一域名不同的url设置不同的后台。,或者对不同的域名指定不同后台等多站配置操作)

然后uswgi可以这么配置协议:

uwsgi --socket 127.0.0.1:3031 --wsgi-file foobar.py --master --processes 4 --threads 2 --stats 127.0.0.1:9191

这说明了服务器的每一个请求都通过3031端口送给uwsgi

配置nginx.conf
  • 首先我们需要一个nginx的参数文件:uwsgi_paramsfile。这个文件要配置到我们的项目的目录下,这一步很容易被忽略!

  • 在**/etc/nginx/sites-available/ **目录下创建一个配置文件:mynginx.conf ,也可以修改default的

    配置文件示例如下,这里配置了两个django项目,一个通过TCP套接字,一个是unix套接字:

      # the upstream component nginx needs to connect to
      #这里主要是做负载均衡的,也是nginx和uwsgi连接的地址
      upstream django {
      #django项目的端口号 和uwsgi里面的端口号保存一制
      server 127.0.0.1:8000; # for a web port socket (we'll use this first)#这里是tcp套接字
      
      }
      
      
      
      # configuration of the server
      
      server {#第一个域名配置
      # nginx服务的端口号 不用修改,HTTP访问通过80端口,
      listen 80;
      # the domain name it will serve for
      # 这里可以填写你的ip地址或者域名,多个域名中间空格隔开
      server_name www.XXX.show;
      charset     utf-8;
        gzip on;
        gzip_disable "msie6";
        gzip_proxied any;
        gzip_min_length 1k;
        gzip_comp_level 4;
        gzip_types text/plain text/css application/json application/x-javascript text/javascript text/xml image/jpeg image/png image/gif;
      # max upload size
      client_max_body_size 75M;   # adjust to taste
          access_log  /home/loverweb/website/logs/nginx/host.access.log;    # 日志文件
          error_log  /home/loverweb/website/logs/nginx/error.log;    # 日志文件
      # Django media
      location /media  {
          alias /home/loverweb/media;  # 指向django的media目录
      }
      
      location /static {
          alias /home/loverweb/static_all; # 指向django的static目录
      }
      
      # Finally, send all non-media requests to the Django server.
      location / {
          uwsgi_pass  127.0.0.1:8000;#nginx与uwsgi通信的接口,这里是TCP端口套接字,还能用unix 套接字
          include     uwsgi_params; # the uwsgi_params file you installed
      }
      }
      #第二个django配置
      upstream IHT {
      #UNIX套接字,一般是使用这个sock文件,这个文件,uwsgi中也配置了,是一样的
      server unix:///home/IHT/Django/mysite.sock;
      }
      server {#第二个域名配置
      # nginx服务的端口号 不用修改,https使用的443端口
      listen 443;
      # the domain name it will serve for
      # 这里可以填写你的ip地址或者名,可以配置多个,空格打开就行
      server_name www.XXX.fun;
      #https的ssl证书配置,阿里云可以申请免费的ssl证书,
      ssl on;
      ssl_certificate /home/IHT/Django/ssl/www.XXX.fun.pem;
      ssl_certificate_key /home/IHT/Django/ssl/www.XXX.fun.key;
      ssl_session_timeout 5m;
      ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_prefer_server_ciphers on;
      charset     utf-8;
        gzip on;
        gzip_disable "msie6";
        gzip_proxied any;
        gzip_min_length 1k;
        gzip_comp_level 4;
        gzip_types text/plain text/css application/json application/x-javascript text/javascript text/xml image/jpeg image/png image/gif;
      # max upload size
      client_max_body_size 75M;   # adjust to taste
          access_log  /home/IHT/Django/logs/nginx/host.access.log;    #日志
          error_log  /home/IHT/Django/logs/nginx/error.log;    # 
      # Django media
      location /media/  {
          alias /home/IHT/Django/media/;  # 指向django的media目录
      }
      location /static/ {
          alias /home/IHT/Django/static/; # 指向django的static目录
      }
      # Finally, send all non-media requests to the Django server.
      location / {
          uwsgi_pass  IHT;#nginx和uwsgi连接,注意这个IHT是upstream IHT的名字
          include     /home/IHT/Django/uwsgi_params; # the uwsgi_params file you installed
      }
      }
    
  • 将nginx配置文件链接到sites-available文件夹中,就可以启动nginx了(systemctl start nginx.service)。当sites-available有这个文件时,我们需要把它删掉再进行运行

      	sudo ln -s /etc/nginx/sites-available/mynginx.conf /etc/nginx/sites-enabled/
    

若nginx运行时,提示用户的权限不够,把user = nginx改成user = root即可

配置参考

多域名的nginx配置参考:

- [https://ruanjianlaowang.blog.csdn.net/article/details/93588247?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight](https://ruanjianlaowang.blog.csdn.net/article/details/93588247?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.edu_weight)
- [https://blog.csdn.net/nightelve/article/details/19265421?utm_source=app](https://blog.csdn.net/nightelve/article/details/19265421?utm_source=app)
nginx的命令
  • 启动服务:

      systemctl start nginx.service
    
  • 开机启动

      systemctl enable nginx
    
  • 重启服务

      systemctl restart nginx.service
    
  • 重载配置文件:

      nginx -s reload
    
  • 查看端口号

      nginx -s reload
    
  • 查看进程:

      ps -ef|grep nginx
      ps aux |grep nginx
    
  • 查看是否监听

      ss -tnl | grep 80 
    
  • 查看nginx 启动状态

      systemctl status nginx
    
  • 停止服务

    建议:

      systemctl stop nginx.service
    

    停止的四种命令

    从容停止服务
    这种方法较stop相比就比较温和一些了,需要进程完成当前工作后再停止。

      nginx -s quit
    

    立即停止服务
    这种方法比较强硬,无论进程是否在工作,都直接停止进程。

      nginx -s stop
    

    systemctl 停止
    systemctl属于Linux命令

    systemctl stop nginx.service

    killall 方法杀死进程
    直接杀死进程,在上面无效的情况下使用,态度强硬,简单粗暴!

      killall nginx
    

参考:

[https://blog.csdn.net/weixin_30632899/article/details/99771835?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight](https://blog.csdn.net/weixin_30632899/article/details/99771835?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight)
nginx使用错误

-这个错误一般是配置文件出错了,不能进行启动

nginx.serviceJob for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.

在nginx的目录下运行:

 nginx -t

查看nginx配置文件的错误的地方,然后进行修改即可

django部署配置时,常见的502 Gateway

这个错误查看nginx,发现一般错误如下:

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

这个问题官网有提到,需要提升权限,

  • 最高权限:–chmod-socket=666
  • 稍低的权限: --chmod-socket=664

配置https访问

  • 方法1

    如果要配置https访问,需要配置SSL证书,一般在云服务器商申请即可,然后进行签发,下载nginx格式的,有.pem和.key两个文件。

    腾讯云可以按照这个思路进行申请:https://jingyan.baidu.com/article/d45ad1487ff97669542b8074.html

    申请到证书,上传到服务器,就修改nginx的配置,监听433端口,并且,配置ssl如下:

      server {
      # nginx服务的端口号 不用修改,https配置
      listen 443;
      # the domain name it will serve for
      # 这里可以填写你的ip地址或者名,可以配置多个,空格打开就行
      server_name www.XXX.fun;
      #https的ssl证书配置
      ssl on;
      ssl_certificate /home/Django/ssl/XXX.pem;#pem文件所在的目录
      ssl_session_timeout 5m;
      ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
      ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
      ssl_prefer_server_ciphers on;
      
      ...
      }
    
  • 方法2:

参考:https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html

上面的文档在Security and availability节提到了,以下配置https:

[uwsgi]
shared-socket = :443
https = =0,foobar.crt,foobar.key
uid = foo
gid = bar
chdir = path_to_web2py
module = wsgihandler
master = true
processes = 8

不过这个需要自己手动签发一个ssl文件,利用openssl程序即可完成。

这个方法没有测试过

其他看过的资料:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月司

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值