• day91:luffy:基于vue+drf的路飞学城项目后端部署


    目录

    1.安装mysql镜像

    2.把本地的数据导入到容器的mysql数据库中

    3.安装redis容器

    4.把后端项目部署前的处理

    5.修改项目的配置文件:prod.py

    6.从后端项目中收集静态文件

    7.将后端项目需要的库导出成文件(requirements.txt)

    8.创建后端容器

    9.在后端容器的虚拟环境中安装后端项目需要使用的库

    10.在后端容器中启动uwsgi

    11.使用nginx对uwsgi进行反向代理

    12.针对后端服务器的运营站提供静态文件的访问支持

    HELP:部署期间需要注意的问题

    前端部署传送门:基于vue+drf的路飞学城项目前端部署

    1.安装mysql镜像

    根据我们之前分析的项目部署架构,后端需要需要mysql和redis。所有再此我们需要先把这些外部工具先预装。

    # 1.下载mysql镜像
    docker image pull mysql:5.7
        
    '''-e 设置容器内部的环境变量'''
    # 2.启动mysql容器,MYSQL_ROOT_PASSWORD 指代的就是mysql的root用户的登录密码
    docker run -itd -p3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
    
    '''
    我们可以在任意一个外部网路中,远程链接到数据库中
    注意使用命令远程链接mysql,必须使用的地方有mysql
    '''
    # mysql -hIP -P端口 -uroot -p密码
    mysql -uroot -p123456 -h49.232.222.17 -P3306

    Tip:如果出现多台服务器

    # 如果需要多台mysql容器安装在一台服务器中,那么容器内部的端口可以不用设置,但是真实物理系统的端口必须要修改,保证端口唯一!
    docker run -itd -p3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
    docker run -itd -p3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

    2.把本地的数据导入到容器的mysql数据库中

    # 1.虚拟机远程链接数据库
    mysql -uroot -p123456 -h39.102.132.191
    
    # 2.在服务器的mysql创建数据库
    create database luffy charset=utf8mb4;
    
    # 3.把虚拟机本地的数据库导出到桌面
    mysqldump -uroot -p123 luffy > ~/Desktop/data.sql
    
    # 4.把桌面下导出的数据库文件导入到docker容器中的mysql数据库
    mysql -uroot -p123456 -h39.102.132.191 luffy <  ~/Desktop/data.sql

    3.安装redis容器

    # 1.我们需要在docker中下载redis和mysql的容器
    docker pull redis
    
    # 2.创建redis容器并运行redis
    docker run -itd -p6379:6379 redis
        
    # 3.可以进入到容器中,进行测试redis是否已经成功启动
    docker container exec -it <容器名称/容器ID> bash
    
    # 容器内部,执行 redis-cli

    4.把后端项目部署前的处理

    1. 现在的配置,保存在dev.py中,不管数据库密码或者redis的地址或者配置信息都是属于开发阶段,
    项目上线以后,肯定换成公司的。所以一定会修改,我们需要把dev.py的内容移动到prod.py中,
    并修改对应的配置信息

    2. 在本地开发时,我们使用的框架运行在debug模式下的,但是项目上线时,会关闭debug,所以我们如果关闭了debug模式,则drf框架会不再提供静态文件的浏览服务,也就是之前xadmin,drf的接口页面的图片,样式或者js文件都不能访问到了。我们需要收集这些文件到外界,后面通过nginx来对外提供浏览服务

    3. 原来的drf项目是运行在python内置的提供的web服务器中,wsgiref
    在项目上线的时候,我们不能使用这个模块来提供对外服务!
    不支持多线程,性能不好,本身在安全性上并不完善,python提供这个模块仅供学习和开发测试使用。
    runserver 不能用于生产,改成uwsgi

    4. 原来drf项目在本地开发时,其实要运行这个项目,我们是安装了很多的以来模块。
    将来项目上线了,我们也肯定需要把本地的模块同步到线上服务器!否则项目跑不起来

    5.修改项目的配置文件:prod.py

    # 项目上线了 要将DEBUG的值由True改为False
    DEBUG = False
    
    # ALLOW_HOSTS改为自己的服务器IP地址
    ALLOWED_HOSTS = ['49.232.222.17']
    
    # CORS白名单写自己的前端IP+端口
    CORS_ORIGIN_WHITELIST = (
        'http://49.232.222.17:80', 
    )
    CORS_ALLOW_CREDENTIALS = False 
    
    # 数据库配置要改成服务器的数据库
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "HOST": "49.232.222.17",
            "PORT": 3306,
            "USER": "root",
            "PASSWORD": "123456",
            "NAME": "luffy",
        }
    }
    
    # redis配置要改成服务器的redis
    CACHES = {
        # 默认缓存
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            # 项目上线时,需要调整这里的路径
            "LOCATION": "redis://39.102.132.191:6379/0",
    
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        },
        # 提供给xadmin或者admin的session存储
        "session": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://39.102.132.191:6379/1",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        },
        # 提供存储短信验证码
        "sms_code":{
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://39.102.132.191:6379/2",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            },
        },
        "cart":{
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://39.102.132.191:6379/3",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            },
        }
    }
    
    
    
    # 支付宝配置的同步回调地址和异步结果通知要改成自己的IP/域名
    ALIAPY_CONFIG = {
        ......
        "return_url": "49.232.222.17:80/payment/result",  # 同步回调地址
        "notify_url": "49.232.222.17:81/payment/result/",  # 异步结果通知
    }
    prod.py需要更改的配置

    更改完配置后,删除logs下的luffy.log文件

    6.从后端项目中收集静态文件

    当Django运行在生产环境中,我们会关闭debug调试,那么项目将不再提供静态文件的支持,需要将静态文件交给静态文件的nginx服务器来提供访问。

    我们先收集所有静态文件。项目中的静态文件除了我们使用的上传文件之外,django本身还有自己的静态文件,如rest_framework、xadmin、admin、ckeditor等。我们需要收集这些静态文件,集中一起放到静态文件服务器中。

    我们要将收集的静态文件放到项目的static目录中,所以先创建目录static。

    Django提供了收集静态文件的方法。先在配置文件中配置收集之后存放的目录

    1.在prod.py中添加如下一行代码

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

    2.在终端下执行如下命令

    python manage.py collectstatic

    3.收集完静态文件之后,将后端代码提交到git码云上(add+commit+push)

    4.在服务器端拉取刚刚上传到git码云的代码(pull)

    7.将后端项目需要的库导出成文件(requirements.txt)

    1.在本地电脑中导出当前虚拟环境中的模块包列表[注意,安装包列表是属于后端项目的,所以放到lyapi目录下面]

    cd ~/Desktop/luffy/luffyapi/docs/
    pip freeze > requirements.txt  # 虚拟环境的python,virtualenv管理ptyhon环境,导出时就没有一些额外的乱七八糟的包了.
    
    '''如果导出有很多乱七八糟的包,使用如下方法导出'''
    while read requirement; do pip install -i https://pypi.douban.com/simple/  $requirement; done < requirements.txt

    2.把本地更改的内容[生成了requirements.txt]通过git提交到码云(add+commit+push)

    3.在服务器端使用git拉取最新的代码(pull)

    8.创建后端容器

    1.创建一个容器(后端),使用ubuntu镜像,并和服务器后端代码做一个软连接

    # 1.创建接下来运行后端项目的容器
    docker pull ubuntu:18.04
    
    # 2. -v前是你服务器后端的完整路径,-v后是你想要映射到容器的哪个目录
    docker run -itd -p 8000:8000 -v /home/luffy/lyapi:/home/luffyapi --name=luffyapi ubuntu
                   
    # 3.进入容器
    docker container exec -it luffyapi bash
    
    # 4.更新镜像源[如果有时间,可以修改这个容器的镜像源]
    apt-get update
    
    # 5.安装基本软件和命令
    apt-get install vim

    2.在后端容器中安装python3、虚拟环境

    # 1.容器内部是没有安装python3的pip工具,所以需要安装
    apt install python3
    # 2.安装完python之后,默认不安装pip,所以需要手动安装
    apt install python3-pip
    
    # 3.使用pip安装虚拟环境
    pip3 install virtualenv -i https://pypi.douban.com/simple/
    pip3 install virtualenvwrapper  -i https://pypi.douban.com/simple/
    
    # 4.配置虚拟环境的环境变量
    mkdir $HOME/.virtualenvs  # 创建文件夹: /root/.virtualenvs,将来通过mkvirtualenv指令创建的虚拟环境就会存到这个目录下面
    
    # 5.执行命令,打开并编辑 ~/.bashrc
    vim  ~/.bashrc
    '''文件末尾添加以下几行代码,:wq 保存退出。'''
    export WORKON_HOME=$HOME/.virtualenvs
    export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3  #默认安装python3
    source /usr/local/bin/virtualenvwrapper.sh
    
    # 6.刷新配置文件
    source ~/.bashrc
    
    # 7.创建虚拟环境
    mkvirtualenv luffy(虚拟环境名称) -p python3
    
    # 8.退出虚拟环境
    deactivate

    9.在后端容器的虚拟环境中安装后端项目需要使用的库

    1.把本地虚拟环境中导出模块包列表,在线上服务器里面容器里重新安装

    (luffy) root@a8554e15a9e7:   # 1.前面有个括号,表示进入了某个虚拟环境
    # 2.手动切换环境: workon 两次tab键,就能看到目前有哪些虚拟环境
    # 3.workon 虚拟环境名称,就进入了
    
    # 1.在容器中同步之前的个人开发环境中安装包列表到当前虚拟环境中 requirements.txt cd /home/luffyapi/docs pip install -r requirements.txt -i https://pypi.douban.com/simple/ # 2.项目中有些包是之前使用下载包方式安装的,则这里需要我们手动安装(比如Xadmin) pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 -i https://pypi.douban.com/simple/ # 3.安装完成这些手动安装的包以后,我们再次执行上面的命令 pip install -r requirements.txt -i https://pypi.douban.com/simple

    10.在后端容器中启动uwsgi

    注意以下操作,均是在虚拟环境中执行的

    1.修改后端容器中的uwsgi.ini文件

    [uwsgi]
    #使用nginx连接时使用,Django程序所在服务器地址
    # socket=0.0.0.0:8000
    #直接做web服务器使用,Django程序所在服务器地址
    http=0.0.0.0:8000
    #项目目录
    chdir=/home/luffyapi
    #项目中wsgi.py文件的目录,相对于项目目录
    wsgi-file=lyapi/wsgi.py
    # 进程数
    processes=4
    # 线程数
    threads=2
    # uwsgi服务器的角色
    master=True
    # 存放进程编号的文件
    pidfile=uwsgi.pid
    # 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的
    daemonize=uwsgi.log
    # 指定依赖的虚拟环境
    virtualenv=/root/.virtualenvs/luffy

    2.启动uwsgi

    进入到有uwsgi.ini的目录,执行下面的指令

    uwsgi --ini uwsgi.ini

    3.运行命令查看uwsgi是否启动了

    ps aux | grep uwsgi

    4.如果已经启动了uwsgi,依然不能够成功运行项目,我们可以查看uwsgi.log来查看错误日志

    常见的两个问题:1.mysql-client的版本检测 2.decode/encode 编码解码问题

    如果还是无法成功运行,就再查看一下luffy.log,看一下是不是后端代码的错误

    11.使用nginx对uwsgi进行反向代理

    1.接下来,我们要使用nginx对uwsgi进行反向代理

    # 接下来进入到前端项目所在的容器内部,编辑 /etc/nginx/conf.d/default.conf配置文件
    docker container exec -it lufei_pc bash
    vim /etc/nginx/conf.d/default.conf

    2.vim修改Nginx配置文件,让Nginx接收到请求后转发给uwsgi服务器

         upstream luffy {
             server 49.232.222.17:8000;
         }
    
         server {
             listen  80;
             server_name 49.232.222.17;
    
             location / {
                 include uwsgi_params;
                 uwsgi_pass luffy;
             }
         }

    3.修改完配置后,重启nginx

    nginx -s reload
    如果没有生效,那么先停止再启动:nginx -s stop停止+nginx启动

    4.接下来,我们就需要把api服务端luffyapi容器里面的uwsgi的运行模式改成socket模式

    [uwsgi]
    #使用nginx连接时使用,Django程序所在服务器地址
    socket=0.0.0.0:8000
    #直接做web服务器使用,Django程序所在服务器地址
    # http=0.0.0.0:8000
    #项目目录
    chdir=/home/luffyapi
    #项目中wsgi.py文件的目录,相对于项目目录
    wsgi-file=luffycity/wsgi.py
    # 进程数
    processes=4
    # 线程数
    threads=2
    # uwsgi服务器的角色
    master=True
    # 存放进程编号的文件
    pidfile=uwsgi.pid
    # 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的
    daemonize=uwsgi.log
    # 指定依赖的虚拟环境
    virtualenv=/root/.virtualenvs/luffy

    12.针对后端服务器的运营站提供静态文件的访问支持

    1.因为之前在前端项目部署的时候,已经有了一个nginx容器,所以我们接下来,就直接让前端的nginx容器同时提供静态文件的访问支持。

    进入前端nginx容器并在nginx的配置文件default.conf里面的server部分中配置提供静态文件的访问!

    先删除前端的vue项目的容器,然后再创建一个新的nginx容器,(因为我们需要在nginx容器上做一个静态文件的新的映射)

    前端项目要映射到容器,同时还要把后端项目的static静态文件目录也要映射到该容器中。

    # 1.先把现有的前端nginx容器打包成镜像
    docker commit  lufei_pc  front
    
    # 2.停止并删除前端nginx服务容器
    docker container stop lufei_pc
    docker container rm lufei_pc
    
    # 3.基于上面的front镜像重新创建一个容器。
    docker run -itd -p 80:80 -v /home/ly31/lycity/dist:/usr/share/nginx/html -v /home/ly31/lyapi/static:/usr/share/nginx/static --name=lyapi_nginx  lyapi_final
                 

    2.创建完容器以后,通过访问客户端url地址,没有问题以后,我们接下里就要在前端容器中编写nginx的配置文件,写上提供静态文件访问支持的配置信息.

    配置文件default.conf:

    upstream luffy {
        server 49.232.222.17:8000;
    
    }
    
    server {
        listen  80;
        server_name 49.232.222.17;
    
        location / {
            include uwsgi_params;
            uwsgi_pass luffy;
        }
        
        location /static {
            root /usr/share/nginx;
        }
        
    }
    
    
    
    
    server {
        listen  81;
        server_name  49.232.222.17;
    
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    
      
    }

    3.重启nginx,使用49.232.222.17访问运营后台,样式就正常了。

    nginx -s reload

    HELP:部署期间需要注意的问题

    1.安全组开放端口的问题

    一定要写正确,否则会导致后端无法访问,数据库无法连接等各种BUG.......

    2.在后端容器中安装requirements.txt的那些库的时候,一定要在虚拟环境下

    3.在部署完之后可能会存在CORS跨域失败问题,暂时先用如下方法解决

    编辑nginx的default.conf文件

    vim /etc/nginx/conf.d/default.conf
    
    upstream luffy {
        server 49.232.222.17:8000;
    }
    
    server {
        listen  81;
        server_name 49.232.222.17;
    
        location / {
             
            # 强制添加CORS请求头信息
        proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header Host $http_host;
            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Methods 'GET, POST, PATCH, DELETE, PUT, OPTIONS';
            add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
            include uwsgi_params;
            uwsgi_pass luffy;
        }
        
        location /static {
            root /usr/share/nginx;
        }
        
    }
    
    
    
    
    server {
        listen       80;
        server_name  49.232.222.17;
    
    
        location / {
            root   /usr/share/nginx/html;
            index  index.html index.htm;
            try_files $uri $uri/ /index.html;
        }
    
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    
    }
      

    4.暂时想到这些,如果后期还能想起来就补充一下......

  • 相关阅读:
    POJ 2251 Dungeon Master
    HDU 3085 Nightmare Ⅱ
    CodeForces 1060 B Maximum Sum of Digits
    HDU 1166 敌兵布阵(树状数组)
    HDOJ 2050 折线分割平面
    HDU 5879 Cure
    HDU 1878 欧拉回路
    HDU 6225 Little Boxes
    ZOJ 2971 Give Me the Number
    HDU 2680 Choose the best route
  • 原文地址:https://www.cnblogs.com/libolun/p/13999749.html
Copyright © 2020-2023  润新知