2.把本地的數(shù)據(jù)導(dǎo)入到容器的mysql數(shù)據(jù)庫中 7.將后端項(xiàng)目需要的庫導(dǎo)出成文件(requirements.txt) 9.在后端容器的虛擬環(huán)境中安裝后端項(xiàng)目需要使用的庫 11.使用nginx對(duì)uwsgi進(jìn)行反向代理 12.針對(duì)后端服務(wù)器的運(yùn)營(yíng)站提供靜態(tài)文件的訪問支持 前端部署傳送門:基于vue+drf的路飛學(xué)城項(xiàng)目前端部署 1.安裝mysql鏡像根據(jù)我們之前分析的項(xiàng)目部署架構(gòu),后端需要需要mysql和redis。所有再此我們需要先把這些外部工具先預(yù)裝。 # 1.下載mysql鏡像docker image pull mysql:5.7 '''-e 設(shè)置容器內(nèi)部的環(huán)境變量'''# 2.啟動(dòng)mysql容器,MYSQL_ROOT_PASSWORD 指代的就是mysql的root用戶的登錄密碼docker run -itd -p3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7'''我們可以在任意一個(gè)外部網(wǎng)路中,遠(yuǎn)程鏈接到數(shù)據(jù)庫中 注意使用命令遠(yuǎn)程鏈接mysql,必須使用的地方有mysql'''# mysql -hIP -P端口 -uroot -p密碼mysql -uroot -p123456 -h49.232.222.17 -P3306 Tip:如果出現(xiàn)多臺(tái)服務(wù)器# 如果需要多臺(tái)mysql容器安裝在一臺(tái)服務(wù)器中,那么容器內(nèi)部的端口可以不用設(shè)置,但是真實(shí)物理系統(tǒng)的端口必須要修改,保證端口唯一!docker run -itd -p3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7docker run -itd -p3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7 2.把本地的數(shù)據(jù)導(dǎo)入到容器的mysql數(shù)據(jù)庫中# 1.虛擬機(jī)遠(yuǎn)程鏈接數(shù)據(jù)庫mysql -uroot -p123456 -h39.102.132.191# 2.在服務(wù)器的mysql創(chuàng)建數(shù)據(jù)庫create database luffy charset=utf8mb4;# 3.把虛擬機(jī)本地的數(shù)據(jù)庫導(dǎo)出到桌面mysqldump -uroot -p123 luffy > ~/Desktop/data.sql# 4.把桌面下導(dǎo)出的數(shù)據(jù)庫文件導(dǎo)入到docker容器中的mysql數(shù)據(jù)庫mysql -uroot -p123456 -h39.102.132.191 luffy < ~/Desktop/data.sql 3.安裝redis容器# 1.我們需要在docker中下載redis和mysql的容器docker pull redis# 2.創(chuàng)建redis容器并運(yùn)行redisdocker run -itd -p6379:6379 redis # 3.可以進(jìn)入到容器中,進(jìn)行測(cè)試redis是否已經(jīng)成功啟動(dòng)docker container exec -it <容器名稱/容器ID> bash# 容器內(nèi)部,執(zhí)行 redis-cli 4.把后端項(xiàng)目部署前的處理1. 現(xiàn)在的配置,保存在dev.py中,不管數(shù)據(jù)庫密碼或者redis的地址或者配置信息都是屬于開發(fā)階段, 2. 在本地開發(fā)時(shí),我們使用的框架運(yùn)行在debug模式下的,但是項(xiàng)目上線時(shí),會(huì)關(guān)閉debug,所以我們?nèi)绻P(guān)閉了debug模式,則drf框架會(huì)不再提供靜態(tài)文件的瀏覽服務(wù),也就是之前xadmin,drf的接口頁面的圖片,樣式或者js文件都不能訪問到了。我們需要收集這些文件到外界,后面通過nginx來對(duì)外提供瀏覽服務(wù) 3. 原來的drf項(xiàng)目是運(yùn)行在python內(nèi)置的提供的web服務(wù)器中,wsgiref 4. 原來drf項(xiàng)目在本地開發(fā)時(shí),其實(shí)要運(yùn)行這個(gè)項(xiàng)目,我們是安裝了很多的以來模塊。 5.修改項(xiàng)目的配置文件:prod.py# 項(xiàng)目上線了 要將DEBUG的值由True改為FalseDEBUG = False# ALLOW_HOSTS改為自己的服務(wù)器IP地址ALLOWED_HOSTS = ['49.232.222.17']# CORS白名單寫自己的前端IP+端口CORS_ORIGIN_WHITELIST = ( 'http://49.232.222.17:80', ) CORS_ALLOW_CREDENTIALS = False # 數(shù)據(jù)庫配置要改成服務(wù)器的數(shù)據(jù)庫DATABASES = {"default": {"ENGINE": "django.db.backends.mysql","HOST": "49.232.222.17","PORT": 3306,"USER": "root","PASSWORD": "123456","NAME": "luffy", } }# redis配置要改成服務(wù)器的redisCACHES = {# 默認(rèn)緩存"default": {"BACKEND": "django_redis.cache.RedisCache",# 項(xiàng)目上線時(shí),需要調(diào)整這里的路徑"LOCATION": "redis://39.102.132.191:6379/0","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient", } },# 提供給xadmin或者admin的session存儲(chǔ)"session": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://39.102.132.191:6379/1","OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient", } },# 提供存儲(chǔ)短信驗(yàn)證碼"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", }, } }# 支付寶配置的同步回調(diào)地址和異步結(jié)果通知要改成自己的IP/域名ALIAPY_CONFIG = { ......"return_url": "49.232.222.17:80/payment/result", # 同步回調(diào)地址"notify_url": "49.232.222.17:81/payment/result/", # 異步結(jié)果通知} 更改完配置后,刪除logs下的luffy.log文件 6.從后端項(xiàng)目中收集靜態(tài)文件當(dāng)Django運(yùn)行在生產(chǎn)環(huán)境中,我們會(huì)關(guān)閉debug調(diào)試,那么項(xiàng)目將不再提供靜態(tài)文件的支持,需要將靜態(tài)文件交給靜態(tài)文件的nginx服務(wù)器來提供訪問。 我們先收集所有靜態(tài)文件。項(xiàng)目中的靜態(tài)文件除了我們使用的上傳文件之外,django本身還有自己的靜態(tài)文件,如rest_framework、xadmin、admin、ckeditor等。我們需要收集這些靜態(tài)文件,集中一起放到靜態(tài)文件服務(wù)器中。 我們要將收集的靜態(tài)文件放到項(xiàng)目的static目錄中,所以先創(chuàng)建目錄static。 Django提供了收集靜態(tài)文件的方法。先在配置文件中配置收集之后存放的目錄 1.在prod.py中添加如下一行代碼 STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static') 2.在終端下執(zhí)行如下命令 python manage.py collectstatic 3.收集完靜態(tài)文件之后,將后端代碼提交到git碼云上(add+commit+push) 4.在服務(wù)器端拉取剛剛上傳到git碼云的代碼(pull) 7.將后端項(xiàng)目需要的庫導(dǎo)出成文件(requirements.txt)1.在本地電腦中導(dǎo)出當(dāng)前虛擬環(huán)境中的模塊包列表[注意,安裝包列表是屬于后端項(xiàng)目的,所以放到lyapi目錄下面] cd ~/Desktop/luffy/luffyapi/docs/pip freeze > requirements.txt # 虛擬環(huán)境的python,virtualenv管理ptyhon環(huán)境,導(dǎo)出時(shí)就沒有一些額外的亂七八糟的包了.'''如果導(dǎo)出有很多亂七八糟的包,使用如下方法導(dǎo)出'''while read requirement; do pip install -i https://pypi.douban.com/simple/ $requirement; done < requirements.txt 2.把本地更改的內(nèi)容[生成了requirements.txt]通過git提交到碼云(add+commit+push) 3.在服務(wù)器端使用git拉取最新的代碼(pull) 8.創(chuàng)建后端容器1.創(chuàng)建一個(gè)容器(后端),使用ubuntu鏡像,并和服務(wù)器后端代碼做一個(gè)軟連接 # 1.創(chuàng)建接下來運(yùn)行后端項(xiàng)目的容器docker pull ubuntu:18.04# 2. -v前是你服務(wù)器后端的完整路徑,-v后是你想要映射到容器的哪個(gè)目錄docker run -itd -p 8000:8000 -v /home/luffy/lyapi:/home/luffyapi --name=luffyapi ubuntu # 3.進(jìn)入容器docker container exec -it luffyapi bash# 4.更新鏡像源[如果有時(shí)間,可以修改這個(gè)容器的鏡像源]apt-get update# 5.安裝基本軟件和命令apt-get install vim 2.在后端容器中安裝python3、虛擬環(huán)境 # 1.容器內(nèi)部是沒有安裝python3的pip工具,所以需要安裝apt install python3# 2.安裝完python之后,默認(rèn)不安裝pip,所以需要手動(dòng)安裝apt install python3-pip# 3.使用pip安裝虛擬環(huán)境pip3 install virtualenv -i https://pypi.douban.com/simple/pip3 install virtualenvwrapper -i https://pypi.douban.com/simple/# 4.配置虛擬環(huán)境的環(huán)境變量mkdir $HOME/.virtualenvs # 創(chuàng)建文件夾: /root/.virtualenvs,將來通過mkvirtualenv指令創(chuàng)建的虛擬環(huán)境就會(huì)存到這個(gè)目錄下面# 5.執(zhí)行命令,打開并編輯 ~/.bashrcvim ~/.bashrc'''文件末尾添加以下幾行代碼,:wq 保存退出。'''export WORKON_HOME=$HOME/.virtualenvs export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 #默認(rèn)安裝python3source /usr/local/bin/virtualenvwrapper.sh# 6.刷新配置文件source ~/.bashrc# 7.創(chuàng)建虛擬環(huán)境mkvirtualenv luffy(虛擬環(huán)境名稱) -p python3# 8.退出虛擬環(huán)境deactivate 9.在后端容器的虛擬環(huán)境中安裝后端項(xiàng)目需要使用的庫1.把本地虛擬環(huán)境中導(dǎo)出模塊包列表,在線上服務(wù)器里面容器里重新安裝 (luffy) root@a8554e15a9e7: cd /home/luffyapi/-r requirements.txt -i https://pypi.douban.com/simple/pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 -i https://pypi.douban.com/simple/pip install -r requirements.txt -i https://pypi.douban.com/simple 10.在后端容器中啟動(dòng)uwsgi注意以下操作,均是在虛擬環(huán)境中執(zhí)行的 1.修改后端容器中的uwsgi.ini文件 [uwsgi]#使用nginx連接時(shí)使用,Django程序所在服務(wù)器地址# socket=0.0.0.0:8000#直接做web服務(wù)器使用,Django程序所在服務(wù)器地址http=0.0.0.0:8000#項(xiàng)目目錄chdir=/home/luffyapi#項(xiàng)目中wsgi.py文件的目錄,相對(duì)于項(xiàng)目目錄wsgi-file=lyapi/wsgi.py# 進(jìn)程數(shù)processes=4# 線程數(shù)threads=2# uwsgi服務(wù)器的角色master=True# 存放進(jìn)程編號(hào)的文件pidfile=uwsgi.pid# 日志文件,因?yàn)閡wsgi可以脫離終端在后臺(tái)運(yùn)行,日志看不見。我們以前的runserver是依賴終端的daemonize=uwsgi.log# 指定依賴的虛擬環(huán)境virtualenv=/root/.virtualenvs/luffy 2.啟動(dòng)uwsgi 進(jìn)入到有uwsgi.ini的目錄,執(zhí)行下面的指令 uwsgi --ini uwsgi.ini 3.運(yùn)行命令查看uwsgi是否啟動(dòng)了 ps aux | grep uwsgi 4.如果已經(jīng)啟動(dòng)了uwsgi,依然不能夠成功運(yùn)行項(xiàng)目,我們可以查看uwsgi.log來查看錯(cuò)誤日志 常見的兩個(gè)問題:1.mysql-client的版本檢測(cè) 2.decode/encode 編碼解碼問題 如果還是無法成功運(yùn)行,就再查看一下luffy.log,看一下是不是后端代碼的錯(cuò)誤 11.使用nginx對(duì)uwsgi進(jìn)行反向代理1.接下來,我們要使用nginx對(duì)uwsgi進(jìn)行反向代理 # 接下來進(jìn)入到前端項(xiàng)目所在的容器內(nèi)部,編輯 /etc/nginx/conf.d/default.conf配置文件docker container exec -it lufei_pc bash vim /etc/nginx/conf.d/default.conf 2.vim修改Nginx配置文件,讓Nginx接收到請(qǐng)求后轉(zhuǎn)發(fā)給uwsgi服務(wù)器 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 如果沒有生效,那么先停止再啟動(dòng):nginx -s stop停止+nginx啟動(dòng) 4.接下來,我們就需要把a(bǔ)pi服務(wù)端luffyapi容器里面的uwsgi的運(yùn)行模式改成socket模式 [uwsgi]#使用nginx連接時(shí)使用,Django程序所在服務(wù)器地址socket=0.0.0.0:8000#直接做web服務(wù)器使用,Django程序所在服務(wù)器地址# http=0.0.0.0:8000#項(xiàng)目目錄chdir=/home/luffyapi#項(xiàng)目中wsgi.py文件的目錄,相對(duì)于項(xiàng)目目錄wsgi-file=luffycity/wsgi.py# 進(jìn)程數(shù)processes=4# 線程數(shù)threads=2# uwsgi服務(wù)器的角色master=True# 存放進(jìn)程編號(hào)的文件pidfile=uwsgi.pid# 日志文件,因?yàn)閡wsgi可以脫離終端在后臺(tái)運(yùn)行,日志看不見。我們以前的runserver是依賴終端的daemonize=uwsgi.log# 指定依賴的虛擬環(huán)境virtualenv=/root/.virtualenvs/luffy 12.針對(duì)后端服務(wù)器的運(yùn)營(yíng)站提供靜態(tài)文件的訪問支持1.因?yàn)橹霸谇岸隧?xiàng)目部署的時(shí)候,已經(jīng)有了一個(gè)nginx容器,所以我們接下來,就直接讓前端的nginx容器同時(shí)提供靜態(tài)文件的訪問支持。 進(jìn)入前端nginx容器并在nginx的配置文件default.conf里面的server部分中配置提供靜態(tài)文件的訪問! 先刪除前端的vue項(xiàng)目的容器,然后再創(chuàng)建一個(gè)新的nginx容器,(因?yàn)槲覀冃枰趎ginx容器上做一個(gè)靜態(tài)文件的新的映射) 前端項(xiàng)目要映射到容器,同時(shí)還要把后端項(xiàng)目的static靜態(tài)文件目錄也要映射到該容器中。 # 1.先把現(xiàn)有的前端nginx容器打包成鏡像docker commit lufei_pc front# 2.停止并刪除前端nginx服務(wù)容器docker container stop lufei_pc docker container rm lufei_pc# 3.基于上面的front鏡像重新創(chuàng)建一個(gè)容器。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.創(chuàng)建完容器以后,通過訪問客戶端url地址,沒有問題以后,我們接下里就要在前端容器中編寫nginx的配置文件,寫上提供靜態(tài)文件訪問支持的配置信息. 配置文件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訪問運(yùn)營(yíng)后臺(tái),樣式就正常了。 nginx -s reload HELP:部署期間需要注意的問題1.安全組開放端口的問題 一定要寫正確,否則會(huì)導(dǎo)致后端無法訪問,數(shù)據(jù)庫無法連接等各種BUG....... 2.在后端容器中安裝requirements.txt的那些庫的時(shí)候,一定要在虛擬環(huán)境下 3.在部署完之后可能會(huì)存在CORS跨域失敗問題,暫時(shí)先用如下方法解決 編輯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 / { # 強(qiáng)制添加CORS請(qǐng)求頭信息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.暫時(shí)想到這些,如果后期還能想起來就補(bǔ)充一下...... |
|