以 Docker方式發(fā)布SpringBoot 應(yīng)用
一、為什么要用 Docker方式來(lái)發(fā)布
想用 Docker 來(lái)部署應(yīng)用其實(shí)已經(jīng)滿長(zhǎng)時(shí)間了,苦于沒(méi)有時(shí)間認(rèn)真研究,一直忙于 代碼的編寫,二來(lái)也沒(méi)有什么需要多次重復(fù)部署的需求。當(dāng)然第二點(diǎn)更直接。所以都沒(méi)認(rèn)真看過(guò)文檔。
進(jìn)來(lái)有個(gè)上線的系統(tǒng),需要同時(shí)部署多份,才發(fā)現(xiàn),確實(shí)有些麻煩,如果維護(hù)則更加麻煩。數(shù)據(jù)庫(kù)安裝、java 環(huán)境參數(shù)、應(yīng)用程序,都需要考慮,頭緒太多了。所以 Docker 化部署再次提及日程。
經(jīng)過(guò)一段研究已經(jīng)小有成效,記錄下來(lái)以備忘記的時(shí)候重新恢復(fù)記憶使用。Ubuntu 14.04 LTS 環(huán)境測(cè)試通過(guò)。
二、環(huán)境準(zhǔn)備
已經(jīng)可以上線跑的一個(gè) SpringBoot 應(yīng)用,比如它有一下的目錄結(jié)構(gòu),簡(jiǎn)單起見,我用通配符代表很多文件。假設(shè)應(yīng)用默認(rèn)服務(wù)于 9200 端口。
/root/app1/app.jar /root/app1/T/*.* /root/app1/res/*.* /root/app1/application.yml確保本地應(yīng)用已經(jīng)可以正常運(yùn)行。
安裝 docker,不贅述,各個(gè)操作系統(tǒng)方法不一致。不在此文討論。
三、概念準(zhǔn)備
1.Docker 相關(guān)概念
- Docker鏡像。我們理解 Docker 鏡像可以拿大家比較熟悉的 GHOST 鏡像來(lái)想比較一下。你安裝一個(gè) windows 可以選擇用 ghost 來(lái)加速安裝,這樣很多軟件,驅(qū)動(dòng),一次性就安裝好了。Docker 鏡像也是這樣的,有人事先安裝配置好一定的環(huán)境,你下載好鏡像,運(yùn)行起來(lái)就可以獲得這個(gè)環(huán)境的功能;鏡像有很重要的幾個(gè)屬性,Repository、Tag、ImageId,分別可以理解為鏡像名稱、版本、全局不重復(fù)編號(hào)
- Docker 容器。Docker鏡像運(yùn)行起來(lái)以后,docker 會(huì)將它加載到一個(gè)容器,容器可以理解為一個(gè)通用的盒子,裝入不同的鏡像,就可以提供不同的功能。容器就一個(gè)黑盒子,你可以為它指定運(yùn)行的鏡像,開放的端口等等。
2.Dockerfile
FROM 指令,可以理解為底包,就是我們要 build 我們自己的鏡像的時(shí)候,是以哪個(gè)鏡像為基礎(chǔ)的。這個(gè)比較好理解就是,如果我們做的是一個(gè) springboot 應(yīng)用的發(fā)布,那么一定是以 java 為底包來(lái)擴(kuò)展的
-
ADD 指令,作用是在建立鏡像的時(shí)候需要將本地的文件加入到鏡像內(nèi)的指令。它把以/結(jié)尾的名稱看做目錄,而把沒(méi)有的部分看做文件。所以如果你想把本地的/T/文件在創(chuàng)建時(shí)候打包到鏡像的 root目錄里面去,那么你需要寫。特別要省略/,文件就正常寫就 OK 了。
ADD /T/ /root/T/
WORKDIR 指令,指定鏡像內(nèi)執(zhí)行命令的默認(rèn)工作路徑,這個(gè)非常重要,鏡像啟動(dòng)后一定會(huì)需要你在某個(gè)特定的位置去執(zhí)行命令,如果不指定這個(gè)工作目錄路徑,很容易造成指令找不到配置或靜態(tài)文件等問(wèn)題。
ENTRYPOINT 指令,Docker啟動(dòng)后執(zhí)行的那個(gè)守護(hù)進(jìn)程的命令。這個(gè)命令執(zhí)行后,需要是一個(gè)可以 hold 住 docker 的一個(gè)程序,讓這個(gè)容器始終處于活躍狀態(tài),一般一個(gè)服務(wù)就能達(dá)到這種效果,所以這里我們把 jar 包運(yùn)行起來(lái)的命令當(dāng)做入口命令
四、實(shí)操
1.編寫 Dockerfile
這里我們假定,將我們的程序部署在 docker 鏡像的 root 目錄中去,docker 啟動(dòng)后執(zhí)行我們的 app.jar 包
FROM java:8
MAINTAINER pcode@mtttt.cn
ADD app.jar /root/app.jar
ADD ./res/ /root/res/
ADD ./lib/ /root/lib/
ADD ./T/ /root/T/
WORKDIR /root/
ENTRYPOINT ["java","-jar","app.jar"]
2.Build鏡像
講了很多,實(shí)際上真的要去做了,內(nèi)容并不多。將上面的內(nèi)容編寫進(jìn)一個(gè) Dockerfile,存放在于 app.jar 一個(gè)目錄內(nèi)
docker build -f Dockerfile .
默認(rèn)創(chuàng)建的 docker鏡像沒(méi)有 tag,可以手動(dòng)運(yùn)行 docker tag 名來(lái)來(lái)指定 tag 比如 docker tag imageid 鏡像名:標(biāo)簽 這樣就搞定了。
? docker images
就會(huì)發(fā)現(xiàn)我們打包好的鏡像已經(jīng)在了。
3.運(yùn)行鏡像
假定我們的程序跑在 9020 端口,那么接下來(lái)就是最后一步了。
docker run -d -p 8080:9020 imageid
我們把鏡像中的 9020 端口映射到 host server 的 8080 端口上,這樣就可以直接訪問(wèn) server 的 8080 端口來(lái)使用服務(wù)了;
五、導(dǎo)出導(dǎo)入容器
docker export 290b8d571b59e137d62be1 > update.tar
注意要根據(jù)實(shí)際情況替換鏡像的 id
docker import - update < update.tar
六、導(dǎo)入導(dǎo)出鏡像
save
命令
docker save [options] images [images...]
示例
docker save -o nginx.tar nginx:latest
或
docker save > nginx.tar nginx:latest
其中-o和>表示輸出到文件,nginx.tar為目標(biāo)文件,nginx:latest是源鏡像名(name:tag)
load
命令
docker load [options]
示例
docker load -i nginx.tar