Web應(yīng)用通常由多個(gè)部分組成,包括:前端羔味、后端和基礎(chǔ)中間件河咽。前端代碼是靜態(tài)的(html+js),可以放在nginx中運(yùn)行赋元;后端業(yè)務(wù)邏輯在nodejs或java容器中運(yùn)行忘蟹;mysql飒房、mongodb等通用中間件進(jìn)行數(shù)據(jù)持久存儲(chǔ)。本文以一個(gè)實(shí)際項(xiàng)目為例媚值,演示如何利用docker方便運(yùn)維對(duì)應(yīng)用的多個(gè)部分進(jìn)行發(fā)布狠毯。
項(xiàng)目概述
項(xiàng)目地址:https://github.com/jasony62/tms-mongodb-web
項(xiàng)目包括3個(gè)部分:
- ue_admin:前端代碼,采用VUE開(kāi)發(fā)褥芒,放在nginx中獨(dú)立運(yùn)行
- back:后端代碼嚼松,采用nodejs開(kāi)發(fā),獨(dú)立運(yùn)行
- mongodb:數(shù)據(jù)持久化喂很,獨(dú)立運(yùn)行
通過(guò)docker要解決兩方面問(wèn)題:1惜颇、減輕開(kāi)發(fā)人員個(gè)人開(kāi)發(fā)環(huán)境的搭建,讓項(xiàng)目具備單機(jī)開(kāi)箱即用能力少辣;2凌摄、實(shí)現(xiàn)代碼和運(yùn)行環(huán)境的整體發(fā)布,簡(jiǎn)化并規(guī)范運(yùn)維工作漓帅。
問(wèn)題1通過(guò)編寫(xiě)docker-compose.yml解決锨亏。相關(guān)知識(shí)可以參考前一篇文章:用Docker簡(jiǎn)化Nodejs開(kāi)發(fā)1——開(kāi)發(fā)環(huán)境。需要注意的是前端代碼獨(dú)立部署有跨域(CORS)問(wèn)題忙干,需要在nginx上設(shè)置反向代理器予。
本文的重點(diǎn)是關(guān)注問(wèn)題2,通過(guò)docker實(shí)現(xiàn)一個(gè)完整的從開(kāi)發(fā)到測(cè)試的發(fā)布流程捐迫。
基本發(fā)布流程如下:
- 開(kāi)發(fā)人員在開(kāi)發(fā)環(huán)境將代碼發(fā)布到git倉(cāng)庫(kù)乾翔;
- 運(yùn)維人員在構(gòu)建環(huán)境從git倉(cāng)庫(kù)拉取代碼;編譯前端代碼施戴;分別將不同模塊打包成鏡像反浓;
- 構(gòu)建環(huán)境將鏡像發(fā)布到私有鏡像倉(cāng)庫(kù);
- 測(cè)試環(huán)境從鏡像倉(cāng)庫(kù)拉取鏡像赞哗,啟動(dòng)運(yùn)行雷则;
- 測(cè)試通過(guò)后,生產(chǎn)環(huán)境從鏡像倉(cāng)庫(kù)拉取鏡像肪笋,啟動(dòng)運(yùn)行月劈。
為演示上述過(guò)程,準(zhǔn)備3臺(tái)機(jī)器藤乙,開(kāi)發(fā)猜揪,構(gòu)建和測(cè)試,都安裝好docker和docker-compose坛梁。
開(kāi)發(fā)環(huán)境
為了讓前端運(yùn)行環(huán)境更干凈湿右,鏡像中只包含編譯完的靜態(tài)內(nèi)容,所以需要在制作鏡像前執(zhí)行命令生成前端代碼(默認(rèn)在dist目錄)
cnpm i
yarn build 或 npm run build
ue_admin目錄下的nginx.conf
罚勾,back目錄下的config
目錄不放在鏡像中毅人,它們需要在運(yùn)行環(huán)境中進(jìn)行指定。
docker-compose.yml
volumes:
- ./back/config:/usr/src/app/config
volumes:
- ./ue_admin/nginx.conf:/etc/nginx/nginx.conf:ro
If neither ‘rw’ or ‘ro’ is specified then the volume is mounted in read-write mode.
參考:https://docs.docker.com/engine/reference/run/#volume-shared-filesystems
參考:https://hub.docker.com/_/nginx
參考:https://www.nginx.com/blog/deploying-nginx-nginx-plus-docker/
參考:JS-Web項(xiàng)目常見(jiàn)問(wèn)題(3)-前后端分離導(dǎo)致的跨域問(wèn)題分析
構(gòu)建環(huán)境
用樹(shù)莓派3B+作為構(gòu)建環(huán)境(其他環(huán)境也可以)尖殃,安裝docker和docker-compose丈莺,建立私有docker倉(cāng)庫(kù),從github上拉取代碼送丰,制作鏡像缔俄,發(fā)布鏡像到私有倉(cāng)庫(kù)。
安裝docker
sudo curl -sSL https://get.docker.com | sh
時(shí)間有些長(zhǎng)器躏,大約等3分鐘俐载。
按照提示執(zhí)行下面的命令,否則會(huì)報(bào)權(quán)限錯(cuò)誤登失。
sudo usermod -aG docker pi
安裝docker-compose
通過(guò)pyenv安裝python遏佣,通過(guò)pip安裝docker-compose。
sudo apt install zlib1g-dev libreadline-dev libssl-dev libbz2-dev libsqlite3-dev libffi-dev
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash
vi ~/.bash_profile
export PATH="/hom/pi/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
source ~/.bash_profile
pyenv install 3.7.0
pyenv global 3.7.0
pip install docker-compose
搭建私有鏡像庫(kù)
拉壤空恪(pull)arm版本的registry鏡像状婶。
docker pull budry/registry-arm
創(chuàng)建存儲(chǔ)鏡像文件的目錄。
mkdir docker-registry
啟動(dòng)鏡像倉(cāng)庫(kù)容器馅巷。
docker run --name registry-arm -d -p 5000:5000 -v /home/pi/docker-registry:/var/lib/registry --restart always budry/registry-arm
從github拉取代碼
安裝git(如果沒(méi)有安裝過(guò))
sudo apt-get install git
從git庫(kù)拉取代碼膛虫。
編譯代碼
cd tms-mongodb-web/ue_admin
cnpm i
npm run build
檢查是否生成dist
目錄。
制作鏡像
官方MongoDb鏡像沒(méi)有樹(shù)莓派的版本钓猬,需要換成rpi3-mongodb3
稍刀。注意,這時(shí)并不需要修改docker-compose.yml
敞曹,docker支持用docker-compose.override.yml
文件指定需要覆蓋的選項(xiàng)(查看官網(wǎng)文檔中關(guān)于-f
選項(xiàng)的說(shuō)明)账月。
version: '3.7'
services:
mongodb:
image: andresvidal/rpi3-mongodb3
logging:
driver: "json-file"
參考:https://hub.docker.com/r/andresvidal/rpi3-mongodb3
執(zhí)行命令,生成鏡像异雁。
docker-compose build
發(fā)布鏡像
在發(fā)布和獲取鏡像前捶障,需要讓客戶(hù)端支持以http(非https)訪(fǎng)問(wèn)私庫(kù)。
客戶(hù)端直接在界面中設(shè)置纲刀。
在樹(shù)莓派中新建文件/etc/docker/daemon.json
项炼,添加如下內(nèi)容:
{ "insecure-registries": ["192.168.43.30:5000"] }
修改完成后需要重啟docker才能生效。
完成上面的工作示绊,在樹(shù)莓派(私庫(kù))上查看已有的鏡像锭部。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
tms-mw-ue_admin latest bb34d5e9ee16 13 hours ago 21.8MB
tms-mw-back latest 0abb9b5c6cb6 13 hours ago 162MB
nginx alpine 7e9d7b4eafa6 7 days ago 18.4MB
node alpine 30bb03f6ec2e 2 weeks ago 96.6MB
andresvidal/rpi3-mongodb3 latest fca24dc11d8c 23 months ago 366MB
budry/registry-arm latest c440ef8a31ab 24 months ago 139MB
tms-mw-ue_admin
和tms-mw-back
是應(yīng)用的鏡像,需要發(fā)布到私有鏡像庫(kù)面褐。
docker tag tms-mw-back 192.168.43.30:5000/tms-mw-back
docker push 192.168.43.30:5000/tms-mw-back
用開(kāi)發(fā)機(jī)或測(cè)試機(jī)看看是否能夠成功拉取鏡像拌禾。
docker pull 192.168.43.30:5000/tms-mw-back
注意:可以不用tag的操作,直接在docker-compose.override.yml
文件中將鏡像指定為私有庫(kù)鏡像展哭。
back:
image: 192.168.43.30:5000/tms-mw-back
ue_admin:
image: 192.168.43.30:5000/tms-mw-ue_admin
運(yùn)行命令
docker-compose build
鏡像版本
代碼更新了就需要生成新的鏡像版本湃窍,為了方便回滾等需要闻蛀,可以將現(xiàn)有的鏡像版本保留下來(lái)。
docker tag 192.168.43.30:5000/tms-mw-ue_admin:latest 192.168.43.30:5000/tms-mw-ue_admin:v1
原則上您市,每一次生成新版本鏡像前觉痛,都應(yīng)該將現(xiàn)有最新版本(latest)標(biāo)記為一個(gè)指定版本號(hào)的鏡像。
參考:https://docs.docker.com/engine/reference/commandline/tag/
測(cè)試環(huán)境
安裝docker和docker-compose茵休。
復(fù)制docker-compose.yml
薪棒,ue_admin/nginx.conf
和back/config
到測(cè)試環(huán)境項(xiàng)目根目錄下。修改docker-compose.yml
文件中進(jìn)行的位置和文件的位置榕莺。
version: '3.7'
services:
mongodb:
image: mongo:latest
container_name: tms-mw-mongo
ports:
- '27017:27017'
logging:
driver: none
back:
image: 192.168.43.30:5000/tms-mw-back
container_name: tms-mw-back
ports:
- '3000:3000'
volumes:
- ./config:/usr/src/app/config
depends_on:
- mongodb
ue_admin:
image: 192.168.43.30:5000/tms-mw-ue_admin
container_name: tms-mw-ue_admin
ports:
- '8080:80'
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- back
docker-compose up
如果鏡像的版本更新了俐芯,需要主動(dòng)拉取新版本的鏡像。
docker-compose pull
開(kāi)發(fā)環(huán)境
如果開(kāi)發(fā)環(huán)境可以連私有倉(cāng)庫(kù)钉鸯,那么開(kāi)發(fā)環(huán)境和測(cè)試環(huán)境的部署就沒(méi)有什么區(qū)別吧史,如果不通,可以采用手工導(dǎo)入導(dǎo)出鏡像的方法亏拉。
導(dǎo)出鏡像
docker save ID > xxx.tar
導(dǎo)入鏡像
docker load < xxx.tar
總結(jié)
通過(guò)docker可以將代碼和它依賴(lài)的運(yùn)行環(huán)境打包成一個(gè)整體進(jìn)行發(fā)布扣蜻,通過(guò)docker-compose.override.yml
文件修改鏡像制作參數(shù),通過(guò)啟動(dòng)容器時(shí)用-v
選項(xiàng)指定配置文件和數(shù)據(jù)目錄及塘,可以解決設(shè)置與特定運(yùn)行環(huán)境相關(guān)參數(shù)的需求莽使。
按照上面的流程基本可以實(shí)現(xiàn)基于docker的版本發(fā)布,但是需要手工操作的環(huán)節(jié)太多笙僚,下一步研究如何利用工具將這個(gè)過(guò)程自動(dòng)化芳肌。
本系列其他文章
用Docker簡(jiǎn)化Nodejs開(kāi)發(fā)1——開(kāi)發(fā)環(huán)境
用Docker簡(jiǎn)化Nodejs開(kāi)發(fā)3——用webhook實(shí)現(xiàn)自動(dòng)更新