• 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.暂时想到这些,如果后期还能想起来就补充一下......

  • 相关阅读:
    tshark的命令使用
    svn log查看自己提交的记录
    账号安全 syyh
    Trivy 容器镜像扫描工具学习 syyh
    《关键对话》脑图整理 syyh
    Grafana 任意文件读取漏洞 (CVE202143798)学习 syyh
    容器安全管理 syyh
    【Sass/SCSS】我花4小时整理了的Sass的函数
    【JavaScript使用技巧】三个截取字符串中的子串,你用的哪个
    【SVG】为了前端页面的美丽,我选择学习SVG
  • 原文地址:https://www.cnblogs.com/libolun/p/13999749.html
Copyright © 2020-2023  润新知