您好,登錄后才能下訂單哦!
Docker通過對于在Dockerfile中的一系列指令的順序解析實現(xiàn)自動的image的構(gòu)建。
通過使用build命令,根據(jù)Dockerfile的描述來構(gòu)建鏡像。
??只支持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ù)
示例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 build -t? IMAGENAME:TAG? .? ??
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存放的目錄中。
我們構(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? file version. 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? file to 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)識
免責(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)容。