溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Dockerfile和docker-compose應(yīng)用

發(fā)布時間:2020-07-18 22:13:03 來源:網(wǎng)絡(luò) 閱讀:405 作者:西出十三歸 欄目:系統(tǒng)運維

Dockerfile 介紹


Docker通過對于在Dockerfile中的一系列指令的順序解析實現(xiàn)自動的image的構(gòu)建。

通過使用build命令,根據(jù)Dockerfile的描述來構(gòu)建鏡像。


Dockerfile指令


??只支持Docker自己定義的一套指令,不支持自定義

??大小寫不敏感,但是建議全部使用大寫

??根據(jù)Dockerfile的內(nèi)容順序執(zhí)行


  • FROM指令

??FROM {base鏡像}

??必須放在DOckerfile的第一行,表示從哪個baseimage開始構(gòu)建


  • MAINTAINER

    MAINTAINER: xxx

    可選的,用來標(biāo)識image作者的地方

  • RUN

??每一個RUN指令都會是在一個新的container里面運行,并提交為一個image作為下一個RUN的base

??一個Dockerfile中可以包含多個RUN,按定義順序執(zhí)行

??RUN支持兩種運行方式:

????RUN <cmd> 這個會當(dāng)作/bin/sh -c “cmd” 運行

????RUN [“executable”,“arg1”,。。],Docker把他當(dāng)作json的順序來解析,因此必須使用雙引號,而且executable需要是完整路徑

?

??RUN?都是啟動一個容器、執(zhí)行命令、然后提交存儲層文件變更。第一層?RUN command1?的執(zhí)行僅僅是當(dāng)前進程,一個內(nèi)存上的變化而已,其結(jié)果不會造成任何文件。而到第二層的時候,啟動的是一個全新的容器,跟第一層的容器更完全沒關(guān)系,自然不可能繼承前一層構(gòu)建過程中的內(nèi)存變化。而如果需要將兩條命令或者多條命令聯(lián)合起來執(zhí)行需要加上&&。如:cd /usr/local/src && wget xxxxxxx


  • ADD & COPY

??當(dāng)在源代碼構(gòu)建的方式下,可以通過ADD和COPY的方式,把host上的文件或者目錄復(fù)制到image中

??ADD和COPY的源必須在context路徑下

??當(dāng)src為網(wǎng)絡(luò)URL的情況下,ADD指令可以把它下載到dest的指定位置,這個在任何build的方式下都可以work

??ADD相對COPY還有一個多的功能,能夠進行自動解壓壓縮包

  • ENV

??ENV key value

??用來設(shè)置環(huán)境變量,后續(xù)的RUN可以使用它所創(chuàng)建的環(huán)境變量

??當(dāng)創(chuàng)建基于該鏡像的container的時候,會自動擁有設(shè)置的環(huán)境變量


  • CMD

??CMD的作用是作為執(zhí)行container時候的默認行為(容器默認的啟動命令)

??當(dāng)運行container的時候聲明了command,則不再用image中的CMD默認所定義的命令

??一個Dockerfile中只能有一個有效的CMD,當(dāng)定義多個CMD的時候,只有最后一個才會起作用

?

CMD定義的三種方式:

??CMD <cmd> 這個會當(dāng)作/bin/sh -c "cmd"來執(zhí)行

??CMD ["executable","arg1",....]

??CMD ["arg1","arg2"],這個時候CMD作為ENTRYPOINT的參數(shù)

Dockerfile示例

示例1 :以最常用的tomcat為示例

1
2
3
4
FROM tomcat:latest
ENV TZ=Asia/Shanghai
RUN?rm?/usr/local/tomcat/webapps?-rf
COPY ./webapps/?/usr/local/tomcat/webapps/




示例解釋:


? ? ? ??基礎(chǔ)鏡像為?tomcat:latest?,基礎(chǔ)鏡像如果本地存在,則使用本地的鏡像,如果不存在,則自動會從官方鏡像倉庫拉取鏡像,查 看鏡像:docker images

? ? ?ENV?設(shè)置時區(qū),亞洲?/?上海

?RUN ??運行命令把?tomcat?自身?webapps?目錄下的內(nèi)容清除

?COPY?把當(dāng)前目錄中的?webapps?目錄拷貝到鏡像中,生成我們自己需要的新的鏡像。


這里有幾個需要注意的地方

  • rm /usr/local/tomcat/webapps -rf? 和? ?rm /usr/local/tomcat/webapps/*? -rf? 的區(qū)別

? ? ? ? ? ?rm /usr/local/tomcat/webapps -rf? ?表示刪除整個webapps目錄,也就是webapps目錄都沒有了


? ? ? ??rm /usr/local/tomcat/webapps/*? -rf? 表示刪除webapps目錄下的東西,也就是webapps目錄還在,但是里的東西沒有了。


  • 程序的war包或者前端包放在什么地方?

? ? ? ? ? ? 這里需要結(jié)合上面的rm 語句的寫法來決定。如果上面寫的是rm /usr/local/tomcat/webapps -rf ,也就是容器里沒有了webapps,那么我們COPY或ADD程序包的時候,會使用?


COPY ./webapps/ /usr/local/tomcat/webapps/? ?這樣的指令,給容器里再COPY進去一個webapps,這種情況的程序包當(dāng)然就放在當(dāng)前目錄的webapps目錄下。

? ? ? ? ?如果是使用的???COPY ./webapps/ /usr/local/tomcat/webapps/* -rf 這樣的指令,那么可以直接把war包或者前端包放到Dockerfile的同級目錄。也即是這樣:

1
2
3
4
5
FROM tomcat:latest
ENV TZ=Asia/Shanghai
RUN?rm?/usr/local/tomcat/webapps/* -rf
COPY *.war?/usr/local/tomcat/webapps/
COPY build??/usr/local/tomcat/webapps/

? ?

示例2:初始的tomcat鏡像不夠我們使用,我們需要下載一些東西,下載一些插件。


1
2
3
4
FROM tomcat:latest
ENV TZ=Asia/Shanghai
RUN?rm?/usr/local/tomcat/webapps?-rf && apt-get update && apt-get?install?-y ffmpeg && apt-get clean
COPY ./webapps/?/usr/local/tomcat/webapps/

示例解釋:

本示例多了一步下載程序的步驟,可以通過?&&?使用一條?RUN?命令完成(RUN指令里也有解釋)。這里是下載了?ffmpeg?插件。

需要注意的是,不同的初始鏡像,鏡像的發(fā)布版本不一樣,也即發(fā)布版本不一定是?centos?版的鏡像。這里的?tomcat?就是使用?debain?鏡像制作而成,那么下載東西得參考?debain?的下載包的方法,具體debain,ubuntu怎么下載包可以網(wǎng)上百度。

?

如何分辨到底是?centos?發(fā)布版本,還是?debain?,或者是?ubuntu??可以查看鏡像官方文檔或者運行一個初始鏡像

docker run -it tomcat:latest bash ????運行一個基礎(chǔ)鏡像

cat ?/etc/debian_version ???debian?系統(tǒng),則?/etc/?目錄下有此文件,可以查看?debian?版本

如果是?centos?系統(tǒng),則有?cat /etc/redhat-release??ubuntu?也有自己相應(yīng)的標(biāo)識。


示例3:添加CMD指令,作為啟動程序的指令

上面的tomcat鏡像,由于在初始鏡像中就已經(jīng)做了CMD啟動指令,這里我換成基礎(chǔ)平臺的鏡像舉例。(tomcat鏡像你也可以自己再寫一條CMD,會覆蓋掉基礎(chǔ)鏡像的啟動指令)

1
2
3
4
5
6
7
[root@localhost app]# cat Dockerfile
FROM microsoft/dotnet:2.2-aspnetcore-runtime
RUN?ln?-s?/lib/x86_64-linux-gnu/libdl-2.24.so?/lib/x86_64-linux-gnu/libdl.so
RUN apt-get update? && apt-get?install?-y net-tools? procps?lsof??sysstat libfontconfig1 libgdiplus &&?ln-s libgdiplus.so gdiplus.dll
#ENV LANG C.UTF-8
COPY? ./JF-ISBM?/etc/JF-ISBM
CMD ["sh","-c","cd? /etc/JF-ISBM/ ;dotnet /etc/JF-ISBM/JF-ISBM2.0WEBAPI.dll"]

示例解釋:基礎(chǔ)鏡像為微軟鏡像倉庫的dotnet2.2鏡像

??????????RUN ?下載基礎(chǔ)平臺需要的依賴包

??????????COPY ?把當(dāng)前目錄的基礎(chǔ)平臺程序拷貝到鏡像中

??????????CMD ?設(shè)置基礎(chǔ)平臺的啟動命令。

需要注意的是:?在設(shè)置程序啟動命令的時候,需要前臺運行,不能后臺運行,如tomcat如果設(shè)置為?startup.sh?方式啟動,則屬于放入后臺啟動,容器運行后會自動退出。解決方式,可以使用?catalina.sh?方式啟動,或者在?startup.sh?啟動后面增加一句,tail -f /usr/local/tomcat/logs/catalina.out?,讓容器前臺有持續(xù)輸出。

Docker構(gòu)建鏡像

? ? docker build -t? IMAGENAME:TAG? .? ??



Docker-compose介紹

docker-compose是一種容器管理方式,我們在生產(chǎn)環(huán)境中啟動一個容器,除了會使用-p 參數(shù)映射容器端口,還會使用很多參數(shù),比如-v 映射目錄,--restart 指定容器重啟方式等,這樣就會造成一條啟動命名會非常的長,使用起來也會很不方便。

除此之外,直接使用docker run命令也只能一次管理一個容器。docker-compose是一種非常方便的docker容器單機編排腳本。

docker-compose的運行方式依托于docker-compose.yml文件,是一種yaml語言風(fēng)格的key-value文件。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
version:?"3"?????#docker-compose版本,根據(jù)docker-compose版本決定,如果版本不對,在運行時會報錯提示應(yīng)該使用的版本
services:?????????#定義服務(wù)
????jf-isgct-web:????# 服務(wù)名,自定義,這里定義的第一個服務(wù)名為jf-isgct-web
????????build: ./web????#build,指定Dockerfile的位置,需要構(gòu)建鏡像時開啟這個參數(shù)
????????restart: always??# restart,容器重啟策略
????????image:? jf-isgct-web:v2-20190901??#運行容器的鏡像名稱,如果是拉取或者需要上傳到私有鏡像倉庫的鏡像,得按照后邊部署文檔中添加私有鏡像倉庫前綴。如果前面添加了build參數(shù),則這里也是新構(gòu)建的鏡像名稱,故再每次更新重新構(gòu)建鏡像時,需要修改版本號以區(qū)分新舊鏡像,方便回滾,回滾時只需修改為舊鏡像版本。
????????privileged:?true???#容器特權(quán)模式
????????container_name: jf-isgct-web???#指定容器名
#??????? mem_limit: 1g #內(nèi)存限制
#??????? cpus: 1??? #cpu限制
????????ports:????#容器暴露端口,冒號前為宿主機端口,冒號后為容器內(nèi)服務(wù)端口
??????????- 6199:6190
????????environment:???#環(huán)境變量,可以添加多組,以-開頭
??????????- TZ=Asia/Shanghai
????????links:???#關(guān)聯(lián)容器,如果有需要關(guān)聯(lián)的容器,可以添加此參數(shù),如果沒有,可不添加
??????????- jf-isgct:backend
????????depends_on:???#依托容器,即該參數(shù)下的容器啟動后才會啟動本服務(wù)容器,根據(jù)需求是否添加
??????????- jf-isgct
#??????? volumes:???? #容器目錄映射,冒號前為映射到宿主機的目錄,可以為相對路徑,冒號后為容器里需要映射出來的目錄
#????????? - ./logs:/usr/local/tomcat/logs
????????command:?"sh -c 'cd /front-end;npm run start'"??#類似Dockerfile中的CMD,添加容器中服務(wù)啟動命令,一個服務(wù)只能出現(xiàn)一條command,并且也是需要前臺啟動
??????
????jf-isgct:??#第二個服務(wù),可以在一個docker-compose.yml中寫多個服務(wù),也可以單獨一個
#??????? build: ./backend??
????????image: 1.xxx.xxx.xxx/zhxy/jf-isgct:v2.0-20180830
????????restart: always
????????container_name: jf-isgct
#??????? mem_limit: 1g #內(nèi)存限制
#??????? #??????? cpus: 1.0
????????ports:
??????????- 12216:8080
????????volumes:
??????????- ./config.txt:/usr/share/JFConfig/config.txt
??????????- ./logs:/usr/local/tomcat/logs
??????????-?/etc/localtime:/etc/localtime:ro
????????command:?"sh -c '/usr/local/tomcat/bin/startup.sh; tail -f /usr/local/tomcat/logs/catalina.out'"

docker-compose?命令使用:

docker-compose up -d ?運行容器

docker-compose down?關(guān)閉容器

docker-compose up -d --build?構(gòu)建新鏡像,并用新鏡像運行一個容器

docker-compose build?只構(gòu)建新鏡像

docker-compose restart 重啟容器

需要注意的是,運行docker-compose命令需要在docker-compose.yml存放的目錄中。


docker鏡像更新

我們構(gòu)建鏡像可能會存在更新的情況。這里介紹兩種方式更新鏡像。

直接使用官方初始鏡像構(gòu)建的鏡像更新

這種方式的初始鏡像為官方鏡像,即FROM 的鏡像為官方鏡像,比如tomcat:latest? ? ,node:10.16? ,?microsoft/dotnet:2.2-aspnetcore-runtime 等都是官方的基礎(chǔ)鏡像。我所有做的公司業(yè)務(wù)鏡像都是以這種方式構(gòu)建。這里以基礎(chǔ)平臺的dotnet 鏡像為例。


1
2
3
4
5
6
FROM microsoft/dotnet:2.2-aspnetcore-runtime
RUN?ln?-s?/lib/x86_64-linux-gnu/libdl-2.24.so?/lib/x86_64-linux-gnu/libdl.so
RUN apt-get update? && apt-get?install?-y net-tools? procps?lsof??sysstat libfontconfig1 libgdiplus &&?ln-s libgdiplus.so gdiplus.dll
#ENV LANG C.UTF-8
COPY? ./JF-ISBM?/etc/JF-ISBM
CMD ["sh","-c","cd? /etc/JF-ISBM/ ;dotnet /etc/JF-ISBM/JF-ISBM2.0WEBAPI.dll"]

?Dockerfile詳解:


這里的初始鏡像為微軟官方下載的?microsoft/dotnet:2.2-aspnetcore-runtime

兩條RUN命令為基礎(chǔ)鏡像所需要的依賴包和一些工具。

COPY命令為把和Dockerfile同級目錄的基礎(chǔ)平臺程序JF-ISBM目錄拷貝到鏡像中

CMD? dotnet啟動基礎(chǔ)平臺

我這里Dockerfile和JF-ISBM放置的目錄為:?/mdata/jf-isbm/app?? ?;mdata標(biāo)準(zhǔn)化部署目錄,jf-isbm,基礎(chǔ)產(chǎn)品目錄,app,程序放置目錄,如果是tomcat的程序,按照Dockerfile的內(nèi)容,可能會在app目錄下存在webapps目錄,具體根據(jù)不同的Dockerfile確定,上文已經(jīng)解釋過。

如果需要更新程序,那么只需要把舊的基礎(chǔ)包替換成新的基礎(chǔ)包,然后再重新運行構(gòu)建鏡像的命令。

在重新構(gòu)建鏡像之前,需要修改docker-compose.yml文件中image字段的版本號。這樣的好處也是顯而易見的,如果新的鏡像不適合上線運行,那么你只需要重新修改docker-compose.yml文件中image字段的版本號為老版本號,重新運行容器即可。

從鏡像倉庫拉取的鏡像需要更新程序

正常情況來講,如果有程序更新,我這邊會做好新的鏡像然后重新推送到鏡像倉庫,你們直接拉取新的鏡像即可。但如果遇到特殊情況,鏡像倉庫的鏡像還未更新,那么就需要在部署環(huán)境中制作鏡像更新了。

由于部署環(huán)境中已經(jīng)存在我們從鏡像倉庫拉取的老版本的鏡像,那么我們可以由此鏡像作為FROM的基礎(chǔ)鏡像,來更新我們的鏡像。

如果我們是直接從倉庫拉取鏡像,我們的部署目錄jf-isbm下可能沒有app目錄,也沒有Dockerfile文件,那么需要我們手動創(chuàng)建一個,按照規(guī)范標(biāo)準(zhǔn)來部署。

在jf-isbm下創(chuàng)建一個app目錄,專門存放程序包,并在app目錄下創(chuàng)建一個Dockerfile。


1
2
3
FROM 1.xxx.xxx.xxx/zhxy/jf-isbm:v2.0-20190830
COPY? ./JF-ISBM?/etc/JF-ISBM
CMD ["sh","-c","cd? /etc/JF-ISBM/ ;dotnet /etc/JF-ISBM/JF-ISBM2.0WEBAPI.dll"]

Dockerfile詳解:


這里的基礎(chǔ)鏡像就是我們已經(jīng)使用的需要更新的舊鏡像了。因為這個鏡像已經(jīng)包含了我們需要的插件,需要的工具,故這里也不需要我們再重新下載,直接把程序包做一個替換,COPY會覆蓋原有的JF-ISBM。

寫完Dockerfile,上傳我們新的包并解壓,名字要跟Dockerfile里的名字保持一致。之后,我們需要修改一下docker-compose.yml文件。

第一處修改,取消掉build行的注釋,因為需要構(gòu)建鏡像,或者是自己在image行的上面的同級別處(也即前面的空格一樣多)添加一個build: ./app 。這里注意,冒號后面有空格,app為docker-compose.yml同級下存放程序和Dockerfile的目錄,如果你的目錄不叫app,請改成你自己的名字。

第二處修改,更改image字段的版本號。


修改完之后,我們就可以docker-compose down? 和docker-compose up -d --build了。

補充以及一些注意事項

1 上傳的文件解壓后注意中文亂碼問題,具體的解決方法在《解決基礎(chǔ)平臺程序包亂碼問題》

2 注意修改版本號,一定記得,修改好處多多

3? docker-compose可能由于版本不同,在version指定的版本可能會出現(xiàn)不能使用的情況,這里在運行的時候會有報錯提示,提示你該使用的版本,如下:會提示你用2.2或者3.3


1
2
3
[root@localhost jf-isbm]# docker-compose build
ERROR: Version?in?"./docker-compose.yml"?is unsupported. You might be seeing this error because you're using the wrong Compose?fileversion. Either specify a supported version (e.g?"2.2"or?"3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the?fileto use version 1.
For?more?on the Compose?file?format?versions, see https://docs.docker.com/compose/compose-file/

4 這里只是舉例了兩個鏡像構(gòu)建和更新,其他的鏡像構(gòu)建類似,參照即可


5 公司私有鏡像倉庫地址http://1.xxx.xxx.xxx

首先設(shè)置私有鏡像倉庫可信任:


vi /etc/docker/daemon.json

{"registry-mirrors": ["http://f1361db2.m.daocloud.io"],

"insecure-registries": ["1.xxx.xxx.xxx"]

}


systemctl restart docker

centos 登陸方式:docker login -u xxx -p xxxx??1.xxx.xxx.xxx

docker pull??1.xxx.xxx.xxx/datacenter/jf-beais:v1.0-20190516? ?拉取鏡像

docker push? ?1.xxx.xxx.xxx/datacenter/jf-beais:v1.0-20190516? 推送鏡像

鏡像的名需要有私有倉庫地址標(biāo)識



向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI