美文网首页Django从入门到精通
django+nginx+uwsgi项目部署

django+nginx+uwsgi项目部署

作者: Python野路子 | 来源:发表于2018-06-02 18:28 被阅读0次

    购买服务器

    可以到阿里云,腾讯云,aws外国的服务器商购买服务器和域名;
    其中各服务商有试用时间段,如果用于测试则可以使用免费的服务器。
    大概步骤:

    1. 选择地区;
    2. 选择系统,一般为ubuntu16.04 x 64;
    3. 自己玩的话,最低配够了,视具体情况而定;
      4.买完之后会让你设置主机登录密码和远程密码;
      image.png
      购买成功之后,我们可以进入主机
      image.png
      输入在购买时所填的远程密码
      image.png
      连接之后输入主机用户(root)和密码(与上面远程密码不是同一个的,取决于你购买服务器时所填的)
      image.png
      然后升级环境
      apt update #新环境一般都更新下
    • 购买域名
      这个自己玩的可要可不要,域名要正常解析的话则国内需要备案,国外不需要


      image.png

      购买好域名备案之后,要将域名解析,绑定公网ip


      image.png
      各操作对应服务商会提供对应操作指引,按照其中执行即可。

    python安装

    一般linux服务器目前都安装python2.x版本,最新的都会装3.x的。可以查看系统中是否安装了python

    #输入python即可查看相关信息
    python2 --version #查看python2的版本信息
    pyton3 --version #查看python3的版本信息
    
    #如需要安装
    sudo apt-get install python3.x   #安装python
    

    Python3和Python2是互相不兼容,但也不能卸载python2,可以将Python的指向Python3,这样就可以默认使用python3了。

    默认指向python2: image.png
    这里来改为指向python3
    echo alias python=python3 >> ~/.bashrc
    source ~/.bashrc   #source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
    
    再来看下,指向python3了: image.png
    需要用2则python2即可 image.png

    安装pip3

    查看pip是否安装 image.png

    如出现以上界面,表示已安装pip了
    但是需要注意是在哪个下面的,是python2还是python3下安装的


    image.png
    默认是装在python2下的
    需要安装python3的:
    apt install python3-pip   #主目录下,这可以可以全局使用pip3
    

    注意

    如果更新了pip image.png

    升级了pip,再次使用pip 安装相关的python包的时候就出现以下错误再来直接使用就会报错


    image.png
    ImportError: cannot import name main
    

    解决:vim /usr/bin/pip3进去

    from pip import main
    if __name__ == '__main__':
        sys.exit(main())
    
    换成下面即可:
    from pip import __main__
    if __name__ == '__main__':
        sys.exit(__main__._main())
    
    image.png

    安装虚拟环境

    virtualenv可以搭建虚拟且独立的python运行环境, 使得单个项目的运行环境与其它项目独立起来,不与其他产生冲突,即安装在虚拟环境里的所有包,均不会对环境外的其他包产生影响,反之,在虚拟环境下运行时只能调用虚拟环境中安装的包,不会调用外部的包。相当于局部和全局之分;

    1. virtualenv本质上是个python包, 使用pip安装,选择建立虚拟环境的文件夹
    pip3 install virtualenv        #安装虚拟环境     
    
    1. 使用virtualenv创建虚拟环境:
    virtualenv  -p /usr/bin/python3 envpro    
    # -p参数指定Python解释器程序路径,这将会使用 /usr/bin/python3 中的Python解释器。在当前目录下创建 envpro虚拟环境
    

    envpro就是新建虚拟环境的目录。envpro下拥有bin、include、lib三个文件夹。本虚拟环境所有安装的Python库将存放在ENV/lib/pythonX.X/site-packages/下。 创建虚拟环境就会装好python,会将系统中的拷贝过来。

    1. 进入虚拟环境,注意:只有激活之后,才算进入该虚拟环境,否则安装包时,依然是安装在全局环境之下:
    source envpro/bin/activate    #每次进入都要这样做,不能直接cd 这个目录进去
    

    这种方式的虚拟环境配置简单,使用也很简单,但是需要记住虚拟环境的名字或者路径,鉴于virtualenv不便于对虚拟环境集中管理,所以推荐直接使用virtualenvwrapper。 virtualenvwrapper提供了一系列命令使得和虚拟环境工作变得便利。它把你所有的虚拟环境都放在一个地方。

    virtualenvwrapper
    #1.安装((确保virtualenv已安装):
    pip3 install virtualenvwrapper
    pip3 install virtualenvwrapper-win  #Windows使用该命令
    #2.创建文件目录:
    mkdir $HOME/.virtualenvs
    #3.在.bashrc中(vim .bashrc)添加:
    export WORKON_HOME=$HOME/.virtualenvs#virtualenvwrapper存放虚拟环境目录
    source /usr/local/bin/virtualenvwrapper.sh 
    #第二行:每次登陆用户自动执行下脚本,virtrualenvwrapper会安装到python的bin目录下,所以该路径是python安装目录下bin/virtualenvwrapper.sh,可用whereis virtualenvwrapper.sh查看virtualenvwrapper.sh的路径。
    #4. 读入配置文件,立即生效
    source ~/.bashrc
    

    ==> 报错:/usr/bin/python: No module named virtualenvwrapper

    image.png 错误原因:错误原因:Ubuntu安装了2.7和3.x两个版本的python,在安装时使用的是sudo pip3 install virtualenvwrapper在我运行的时候默认使用的是python2.x,但在python2.x中不存在对应的模块。(virtualenvwrapper.sh文件内容如下:):
    image.png
    当不存在VIRTUALENVWRAPPER_PYTHON环境时,会默认选择使用which python(我这里默认是python2)
    image.png
    需要增加:export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
    image.png
    就可以重新激活成功:
    image.png
    继续完成后续配置
    #5.创建虚拟环境 mkvirtualenv
    #若想指定python版本,可通过"-p"指定python解释器
    mkvirtualenv -p /usr/bin/python3 blogenv
    #这样会在WORKON_HOME变量指定的目录下新建名为blogenv的虚拟环境。
    #6.使用虚拟环境
    进入:workon blogenv
    退出:deactivate
    #7.删除虚拟环境
    rmvirtualenv blogenv
    
    image.png
    1. 下载所需要的模块:
    PS:python项目中必须包含一个 requirements.txt 文件,用于记录所有依赖包及其精确的版本号。其作用是用来在另一台PC上重新构建项目所需要的运行环境依赖,以便新环境部署。
    # 在以前项目环境里导出环境
    pip freeze > requirements.txt    #生成requirements.txt
    # 在环境里安装相应的模块
    pip install -r requirements.txt   #安装requirements.txt依赖,根据文件进行包安装,可以使用xftp软件把requitements.txt 文件放到传到服务器上,然后指定对应路径安装即可;
    或者
    一个一个安装项目中所需要的模块
    安装Django    pip3 install django   
    安装相应的模块 django-bootstrap4   django-simple-captcha 
    django-ckeditor    django-pure-pagination   pymysql等等
    

    退出虚拟环境:deactivate

    安装数据库

    1. 安装 Mysql : sudo apt-get install mysql-server
      下载完之后进入安装,会提示输入root的密码qmpython
    2. 安装mysql:apt install libmysqlclient-dev
    3. 安装成功后可以通过下面的命令测试是否安装成功:
    netstat -tap | grep mysql
    
    1. 设置mysql允许远程访问,首先编辑文件/etc/mysql/mysql.conf.d/mysqld.cnf
    sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
    
    注释掉bind-address = 127.0.0.1: #允许远程连接
    

    保存退出(:x或者:wq)

    然后进入mysql,mysql -u root -p

    1. 执行授权命令:
    #创建普通用户:
    create user 'username'@'%' IDENTIFIED BY 'password';  #qmpython
    #"%",表示在任何一台电脑上都可以登录,也可以指定某台机器可以远程登录。
    #给普通用户赋权
    grant all on *.* to username@'%';
    #如果要授予该用户对所有数据库和表的相应操作权限则可用*表示, 如*.*.
    
    flush privileges;
    
    然后执行quit命令退出mysql服务
    
    1. 配置完mysql之后需要重启mysql:
    service mysql restart
    

    Django项目部署

    • 此处从git直接clone下来方式部署
    1. 查看有没有git git --version 没有就安装 apt install git;

    2. 新建存放项目的文件夹/src/www

    3. 克隆自己的项目 git clone https://github.com/xx/xxx.git

    4. 修改设置 vim project/settings.py =>ALLOWDE_HOSTS =[“服务器ip”] ;

    5. 修改数据库对应配置;

    6. 迁移,进入项目目录下执行

    python manage.py makemigrations
    python manage.py migrate
    createsuperuser
    
    1. python manage.py runserver 0:8000
    2. 浏览器打开ip或:8000
      如果打开正常则Django 部署成功
      注意:还可以通过pycharm连接阿里云服务器,然后根据同步代码功能同步过来或者XFTP同步文件过来。

    uwsgi

    • WSGI
      Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web server如何与web application通信的规范。

    • uwsgi:与WSGI一样是一种通信协议,是uWSGI服务器的独占协议,用于定义传输信息的类型(type of information),与WSGI协议是两种东西。

    • uWSGI:是一个web服务器,实现了WSGI协议、uwsgi协议、http协议等。

    • 安装需要依赖的包

    apt install python3-dev 
    apt install gcc
    
    • 安装uwsgi
    pip3 install uwsgi         #在虚拟环境里面,具体看实际
    
    • 测试uwsgi
      在虚拟环境中创建test.py文件
      image.png
    #test.py
    def application(env, start_response):
            start_response('200 OK', [('Content-Type','text/html')])
            return [b"hello world"]
    
    

    运行uWSGI:

    uwsgi --http :8000 --wsgi-file test.py
    #http :8000:使用协议http,端口8000
    #wsgi-file test.py:加载指定的文件test.py
    

    这应该直接向端口8000上的浏览器发送“hello world”消息。访问:
    http://www.qmpython.com:8000/ 结果:

    image.png
    如果要运行django项目则如下执行即可:
    进入cd django项目中
    
    uwsgi --http  :8000 --module  项目.wsgi         
    

    浏览器输入ip:port即可查看测试结果
    --卸载

    pip3 uninstall uwsgi
    sudo apt-get remove uwsgi
    

    Nginx

    Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器;同时也是一个IMAP、POP3、SMTP代理服务器;Nginx可以作为一个HTTP服务器进行网站的发布处理,另外Nginx可以作为反向代理进行负载均衡的实现。Nginx就是性能非常好的反向代理服务器,用来做负载均衡。比如静态文件处理,安全,效率等等。

    说到代理,首先我们要明确一个概念,所谓代理就是一个代表、一个渠道,我们先来了解正向代理和反向代理。

    正向代理

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

    image.png

    正向代理的过程,隐藏了真实的请求客户端,服务端不知道真实的客户端是谁,客户端请求的服务都被代理服务器代替来请求。

    反向代理

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

    image.png
    反向代理隐藏了真实的服务端。

    负载均衡

    我们已经了解了代理服务器的概念,Nginx扮演了反向代理服务器的角色,那它根据什么规则进行请求分发的?不用应用场景,分发规则是否可控呢?
    这里提到的客户端发送的、Nginx反向代理服务器接收到的请求数量,就是我们说的负载量。
    请求数量按照一定的规则进行分发到不同的服务器处理的规则,就是一种均衡规则。
    所以~将服务器接收到的请求按照规则分发的过程,称为负载均衡。
    负载均衡在实际项目中,有硬件负载均衡和软件负载均衡两种,硬件负载均衡也称为硬负载,如F5负载均衡,相对造价昂贵成本较高,但是数据的稳定性安全性等等有非常好的保障,如中国移动中国联通这样的公司才会选择硬负载进行操作;更多的公司考虑到成本原因,会选择使用软件负载均衡,软件负载均衡是利用现有的技术结合主机硬件实现的一种消息队列分发机制。

    使用nginx

    • 安装nginx(在虚拟环境外执行)
    apt install nginx  
    
    • 启动重启nginx
      /etc/init.d/nginx start(stop、restart)        
    
    • 测试nginx
    nginx -t        #如果提示13: Permission denied则权限不够,用sudo nginx -t
    #如果failed,则输入nginx -t查看错误信息,找到nginx.conf哪一行出错修改即可。
    

    在浏览器输入ip地址,出现以下情况说明测试成功


    image.png

    PS:可以在浏览器中输入公网IP:端口,端口在阿里云安全组规则里面添加安全组规则端口,nginx默认只允许80,8000(可以通过文件配置,下面会提到)

    nginx + uwsgi + django

    先看下从网上找的图片


    image.png
    image.png

    三者结合起来则需要修改几个配置文件:

    uWSGI文件配置

    /src/www/文件夹下建立两个文件qmblog_uwsgi.iniqmblog_uwsgi_params(这个.ini文件可以放在任何地方)

    image.png
    • qmblog_uwsgi.ini文件
    #配置域应该是uwsgi,记住这个不能丢,否则会报错
    [uwsgi]
    #uwsgi监听的socket,可以为socket文件或ip地址+端口号,用nginx的时候就配socket , 直接运行的时候配 http, http-socket = 127.0.0.1:8080
    socket    = 127.0.0.1:8000
    
    #指定项目的目录,在app加载前切换到当前目录
    chdir           = /root/src/www/CainiaoBlog
    
    # Django的wsgi文件,用来加载blog2/wsgi.py这个模块
    module          =  CainiaoBlog.wsgi
    # Python虚拟环境的路径
    home            = /root/.virtualenvs/blogenv
    # master 启动主进程。
    master   = true
    # 最大数量的工作进程数
    processes   = 10
    # 指定工作进程中的线程数
    threads = 2
    
    # 设置socket的权限
    chmod-socket    = 664
    # 退出的时候是否清理环境,自动移除unix Socket 和 Pid 文件
    vacuum          = true
    #日志文件路径
    daemonize = /root/src/www/logback/uwsgi/blog_uwsgi.log
    
    • qmblog_uwsgi_params
    uwsgi_param  QUERY_STRING       $query_string;
    uwsgi_param  REQUEST_METHOD     $request_method;
    uwsgi_param  CONTENT_TYPE       $content_type;
    uwsgi_param  CONTENT_LENGTH     $content_length;
        
    uwsgi_param  REQUEST_URI        $request_uri;
    uwsgi_param  PATH_INFO          $document_uri;
    uwsgi_param  DOCUMENT_ROOT      $document_root;
    uwsgi_param  SERVER_PROTOCOL    $server_protocol;
    uwsgi_param  REQUSET_SCHEME     $scheme;
    uwsgi_param  HTTPS              $https if_not_empty;
        
    uwsgi_param  REMOTE_ADDR        $remote_addr;
    uwsgi_param  REMOTE_PORT        $remote_port;
    uwsgi_param  SERVER_PORT        $server_port;
    uwsgi_param  SERVER_NAME        $server_name;
    
    • 启动
      进入qmblog_uwsgi.ini文件所在目录执行 uwsgi --ini qmblog_uwsgi.ini 或者在其他目录下执行要加载能访问此配置文件的路径如:uwsgi --ini /root/src/www/qmblog_uwsgi.ini,总而言之,记住一定要在uwsgi起作用的环境下,即在python对应虚拟环境下,且在能访问ini文件目录下执行;
    • 查看
    • 关闭
      sudo pkill -f uwsgi -9
    nginx文件配置

    /root/src/www目录下新建nginx.conf配置文件,内容如下:

    #配置文件内容:
    # 转发给哪个服务器,可以通过upstream配置项让nginx实现负载均衡
    upstream django {    
        server   127.0.0.1:8000; 
        server   127.0.1.1:8000;
    }
    
    # 设定虚拟主机配置,一个http中可以有多个server。
    server {
        # 启动的nginx进程监听请求的端口
        listen      80;
        #定义使用域名访问
        server_name  www.qmpython.com;  
        charset     utf-8;
    
        # max upload size  
        client_max_body_size 75M;    # adjust to taste
    
        # location 配置请求静态文件多媒体文件。
        location /media  {
            alias  /root/src/www/CainiaoBlog/media/;  
        }
        # 静态文件访问的url
        location /static {
            # 指定静态文件存放的目录
            alias /root/src/www/CainiaoBlog/static/;
        }
    
    #  将所有非媒体请求转到Django服务器上
        location / {
            # 包含uwsgi的请求参数,路径为qmblog_uwsgi_params绝对路径
            include  /root/src/www/qmblog_uwsgi_params; 
            # 转交请求给uwsgi
            # uwsgi_pass  127.0.0.1:8000; 
            uwsgi_pass  django;  #这个django对应开头出的,对于动态请求,转发到本机的端口,也就是uwsgi监听的端口,uwsgi运行的主机和ip,后面我们会在本机的该端口上运行uwsgi进程
            # 下面两个配置意思是如果比如通过http://www.xxx.com直接访问的是static下的index.html或者index.htm页面,一般用于将首页静态化
            #root   /root/src/www/CainiaoBlog/static/;
            #index index.html index.htm; 
        }
        #精确匹配不同于上面/,这里http://www.xxx.com会匹配这个,根据这个配置将请求转发给另外nginx服务器,让另外服务器提供静态首页。同上面的访问index.html在另外同一台服务器上同一配置文件中结合。
       # location = / {
        #    proxy_pass  http://ip:port;
      #  }
    }
    

    注意:上面文件引用的路径需要能访问加载到,可以直接在当前路径下cd能进入相应目录下不;
    然后进入

    cd /etc/nginx/sites-enabled
    rm default  #删除默认文件
    ln -s /var/www/nginx.conf nginx.conf  #在此目录下创建软链接
    
    • 重启 nginx
      /etc/init.d/nginx start  (restart、stop)        
    
    image.png
    • 关闭
      /etc/init.d/nginx stop
    
    • 注意:django Nginx设置静态资源,出现403 Forbidden

      如果出现静态文件访问资源403权限问题 image.png
      需要查看主配置文件/etc/nginx/nginx.conf
      image.png

      这个www-data用户不存在,默认安装nginx给的是这个用户,但是程序所属的用户不是它,www-data这个默认的用户,没有静态文件的权限,所以报了个403,没权限,需要改成对应用户即可。


      image.png

    加载/etc/nginx/nginx.conf主配置文件,然后加载前面在sites-enabled中创建的一软链接指向的文件,即我们前面改的配置文件。

    开机自动启动 uwsgi 文件

    which uwsgi 查看在命令在哪个路径下的(/usr/local/bin/uwsgi)
    vim /etc/rc.local
    在exit 0 前加一行

    /etc/init.d/nginx start   #开机自动启动nginx
    /src/www/blogenv/bin/uwsgi --ini /var/www/uwsgi.ini --chmod-socket=666 
    

    然后reboot

    静态文件处理

    1.将settings.py配置文件中DEBUG = False
    说明:
    1)测试环境中打开调试模式,能够显示详细的报错信息,生产环境改为False避免暴露项目内部信息;
    2)生产环境下,即关闭debug后django 不会从 static 目录读取静态文件,静态文件交由nginx去处理;
    2.修改ALLOWED_HOSTS =["*"], “*”表示的就是任意的ip地址,生产部署为了防范攻击,改成本机ip地址和域名;

    在pip安装模块的时候可能是连接的官网速度比较慢,可以使用豆瓣源
    https://pypi.doubanio.com/simple/pip
    如:
    install xxx -i http://pypi.douban.com/simple/

    本人个人博客:www.qmpython.com,就是通过以上方式搭建的。

    欢迎关注微信公众号,一起学习交流

    相关文章

      网友评论

        本文标题:django+nginx+uwsgi项目部署

        本文链接:https://www.haomeiwen.com/subject/dekrsftx.html