博客动态
Hi!欢迎来到Jerry Coding!喜欢请关注!谢谢!有问题可以留言或者点击下面的QQ交流哦!(最近博主划水中。。更新较慢。。。)
微信扫码

扫一扫关注我

More
关于
New
RSS

Django建站历程:(十九)Nginx+uwsgi 部署 django

Jerry 2019年7月16日 697  

       之前一直的调试一直是使用 runserver 命令来运行,这篇博客记录一下我们写好的django博客如何利用nginx和uwsgi部署于生产环境中。

nginx、wsgi、django 三者关系:

       我的理解:wsgi 所扮演的的角色是后端 http 服务器,nginx 扮演的角色是前端 http 服务器,django项目 是客户所真正要访问到的提供数据方。用户从网页浏览器中发出请求,nginx 会一直监听某个(通常是80或者443)端口,收到请求后,反向解析代理将用户的请求转发给 uwsgi 服务器,uwsgi 服务器通过django处理完毕后将结果返回给 nginx,浏览器将最终的结果展现给用户。服务器对外的可以只暴露 80 和 443 端口。

       部署前,我们的项目是这样运行的,我们需要保证这样运行时是没有问题的,有错误的话就根据错误修改:

python3 manage.py runserver 127.0.0.1:8080

部署过程:

一、uwsgi安装配置

1、安装

pip3 install uwsgi

2、创建配置文件 uwsgi.ini

       在工程目录里创建 uwsgi.ini 配置文件,内容大体如下:

[uwsgi]

http = :xxxx

#django 端口号
socket = 127.0.0.1:8001

#django 目录
chdir           = /xxx/xxx/xxx

#虚拟环境路径
virtualenv = /root/.virtualenvs/xxxx_venv/

#Django 项目下 wsgi.py 文件路径
module          = xxxx.wsgi

#主进程
master          = true

#进程数
processes       = 1

#服务器退出的时候自动清理环境
vacuum          = true

#日志记录
daemonize    =  uwsgi/UWSGI.log        

#记录状态服务
stats = uwsgi/uwsgi.status

#指定pid文件的位置,记录主进程的pid号。
pidfile = uwsgi/uwsgi.pid

       相关参数以及解释大体如下:

# 服务相关操作
uwsgi --ini uwsgi.ini             # 启动
uwsgi --reload uwsgi.pid          # 重启
uwsgi --stop uwsgi.pid            # 关闭
uwsgi --connect-and-read uwsgi/uwsgi.status  #读取uwsgi实时状态

# 配置字段相关说明
socket : 地址和端口号,例如:socket = 127.0.0.1:50000

processes : 开启的进程数量

workers : 开启的进程数量,等同于processes(官网的说法是spawn the specified number of  workers / processes)

chdir : 指定运行目录(chdir to specified directory before apps loading)

wsgi-file : 载入wsgi-file(load .wsgi file)

stats : 在指定的地址上,开启状态服务(enable the stats server on the specified address)

threads : 运行线程。由于GIL的存在,我觉得这个真心没啥用。(run each worker in prethreaded mode with the specified number of threads)

master : 允许主进程存在(enable master process)

daemonize : 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器(daemonize uWSGI)。实际上最常用的,还是把运行记录输出到一个本地文件上。

log-maxsize :以固定的文件大小(单位KB),切割日志文件。 例如:log-maxsize = 50000000  就是50M一个日志文件。 

pidfile : 指定pid文件的位置,记录主进程的pid号。

vacuum : 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件(try to remove all of the generated file/sockets)

disable-logging : 
不记录请求信息的日志。只记录错误以及uWSGI内部消息到日志中。如果不开启这项,那么你的日志中会大量出现这种记录:
[pid: 347|app: 0|req: 106/367] 117.116.122.172 () {52 vars in 961 bytes} [Thu Jul  7 19:20:56 2016] POST /post => generated 65 bytes in 6 msecs (HTTP/1.1 200) 2 headers in 88 bytes (1 switches on core 0)

log-maxsize: 日志大小,当大于这个大小会进行切分 (Byte)

log-truncate: 当启动时切分日志

3、 开启服务

       执行一下命令,读取配置,开启服务

uwsgi --ini uwsgi.ini

二、nginx安装配置

1、安装nginx

apt install nginx  

2、配置nginx

       我习惯自己新建一个mysite.conf文件,位置在 /etc/nginx/conf.d/ 下。相关配置如下:

server {
    listen  80; # nginx 监听端口号
    server_name    example.com;
    charset UTF-8;
    access_log      /var/log/nginx/access.log;
    error_log       /var/log/nginx/error.log;

    client_max_body_size 75M;
    
    location /static {
        # 静态文件配置
        root /home/ubuntu/mysite;
     }
    location /media {
        # 媒体文件配置
        root /home/ubuntu/mysite;
     }
    
    location / {
        # 这个地址和uwsgi.ini里面的socket配置一致!
        uwsgi_pass  127.0.0.1:8001;      
        include     uwsgi_params; 
    }
}

       上述一个配置可以实现http 80 端口的访问,如果是https 443端口,大体调地配置文件格式如下:

server {
    # 监听 https 443端口
    listen 443 ssl;   
    server_name    example.com;

    ssl on;                              #开启ssl
    ssl_certificate      cert/*.pem;     #pem 位置
    ssl_certificate_key  cert/*.key;     #key 位置
    ssl_session_timeout  5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 

    #密码加密方式
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; 
    #依赖SSLv3和TLSv1协议的服务器密码将优先于客户端密码
    ssl_prefer_server_ciphers  on;       

    #静态文件处理
    location /static {
            alias /home/www/work/project/pro/;

    #媒体文件处理
    location /media {
            alias /home/www/work/project/pro/;

    其他文件转wsgi处理
    location / {
        #这个是uwsgi.ini中配置的 socket
        uwsgi_pass  x.x.x.x:xxxx;              
        include uwsgi_params;
    }
}

#配置80端口重定向到https 443
server {
   listen 80;
   server_name example.com;
   rewrite ^(.*)$  https://$host$1 permanent;
}

3、开启nginx服务

       首先nginx相关的命令如下:

apt install nginx   //安装
nginx -v            // 查看版本
nginx -c            //设置默认的配置文件
nginx -t            //检查nginx配置是否语法错误
nginx -s reload       //重新加载
nginx -s reopen      //重启
nginx -s stop           //关闭
service nginx start    //启动服务
service nginx stop    // 关闭服务
service nginx restart  //重启服务

       创建了自己的配置文件之后,可以执行 nginx -c xxxxx  来指定为默认的配置文件。nginx -t 可以检查语法错误等。最后nginx -s reload 重启nginx 服务即可。到此,不出意外的话,你应该访问网站的80端口会看到你的博客!大家快来试试吧!

配置中遇到的问题:

1、访问网页80端口或者443端口无法访问?

       要确保那你的服务器的防火墙,有没有放通80端口或者443端口。

2、访问网页80端口一直提示 welcome to nginx 界面?

       这个很坑,你需要修改 /etc/nginx/nginx.conf 文件,找到下面一句注释掉,重启服务再试下:

include /etc/nginx/sites-enabled/*;

3、返回网页为server Error 500 ?

       一般是你的django代码有问题,建议先用manage runserver 调试好再部署。

4、记得部署后,把你的settings.py文件中的 debug 选项改为 False


原创文章,转载请注明出处: https://jerrycoding.com/article/site_building_19

微信
支付宝

您尚未登录,暂时无法评论。请先 登录 或者 注册

2 人参与 | 3 条评论

  • max:
    2019年10月17日

    通过nginx直接用ip访问,样式css和js都加载正常,但是博客的ajax请求都因为缺少端口号而失败,ajax的url直接就是ip加上路径,这要咋解决啊

    • Jerry:
      2019年10月17日

      [@max] :不用nginx是没问题的么?我觉得和nginx是不是没啥关系的

      回复
    • max:
      2019年10月17日

      @[Jerry] :嗯,已经解决了,确实不是nginx的问题,后台代码有点Bug。

      回复