目录
7.将后端项目需要的库导出成文件(requirements.txt)
前端部署传送门:基于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/", # 异步结果通知 }
更改完配置后,删除logs下的luffy.log文件
6.从后端项目中收集静态文件
我们先收集所有静态文件。项目中的静态文件除了我们使用的上传文件之外,django本身还有自己的静态文件,如rest_framework、xadmin、admin、ckeditor等。我们需要收集这些静态文件,集中一起放到静态文件服务器中。
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.
进入前端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
配置文件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.暂时想到这些,如果后期还能想起来就补充一下......