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

posted @ 2020-11-18 14:43  iR-Poke  阅读(373)  评论(0编辑  收藏  举报