1.Dokcer鏡像的創(chuàng)建
創(chuàng)建鏡像有三種方法,分別為【基于已有鏡像創(chuàng)建】、【基于本地模板創(chuàng)建】以及【基于Dockerfile創(chuàng)建】。
1.1 基于現(xiàn)有鏡像創(chuàng)建?
(1)首先啟動(dòng)一個(gè)鏡像,在容器里做修改
?docker run -it --name web centos:7 /bin/bash ? ? #啟動(dòng)容器
??
?yum install -y epel-release ?#安裝epel源
?yum install -y nginx ? ? ? ? #安裝nginx
?yum install net-tools ? ? ? ?#安裝tools工具
?nginx ? ? ? ? ? ? ? ? ? ? ? ?#啟動(dòng)服務(wù)
?netstat -natp |grep 80 ? ? ? #查看端口是否開啟
??
?docker ps -a ? #查看容器ID
??
?(2)然后將修改后的容器提交為新的鏡像,需要使用該容器的ID號(hào)創(chuàng)建新鏡像
?docker commit -m "new nginx" -a "xxxx" 容器id nginx:centos7
?#常用選項(xiàng):
?-m 指定說明信息;
?-a 指定作者信息;
?-p 生成過程中停止容器的運(yùn)行。
?c7f4bc905c29 ?原容器ID。
?nginx:centos ?生成新的鏡像名稱。
??
docker images ? ?#查看生成的新鏡像
docker run -itd nginx:centos7 bash ? ? ? ? ?#使用新的鏡像創(chuàng)建容器
docker ps -a ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#查看容器狀態(tài)
docker exec -it 容器id bash ? ? ? ? ? #進(jìn)入容器
nginx ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #啟動(dòng)nginx服務(wù)
netstat -natp |grep 80 ? ? ? ? ? ? ? ? ? ? ?#查看80端口是否開啟
1.2 基于本地模板創(chuàng)建?
通過導(dǎo)入操作系統(tǒng)模板文件可以生成鏡像,模板可以從OPENVZ 開源項(xiàng)目下載,下載地址為:?
?openvz.org/?Download/template/precreated
‘Download/template/precreated - OpenVZ Virtuozzo Containers Wiki
模板里面就是使用docker export 命令導(dǎo)出的容器文件
??
?#下載模板
?wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
??
?#導(dǎo)入為鏡像,兩種方法
?cat debian-7.0-x86-minimal.tar.gz | docker import - debian:test ?#方法一
??
?docker import debian-7.0-x86-minimal.tar.gz -- debian:test ?#方法二
??
?#查看鏡像
?docker images
??
?#使用導(dǎo)入的鏡像創(chuàng)建容器
?docker run -itd debian:test bash
?docker ps -a
1.3 基于Dockerfile 創(chuàng)建?
聯(lián)合文件系統(tǒng)(UnionFS )?
Union文件系統(tǒng)是Docker鏡像的基礎(chǔ)。鏡像可以通過分層來進(jìn)行繼承,基于基礎(chǔ)鏡像(沒有父鏡像),可以制作各種具體的應(yīng)用鏡像。
特性: 一次同時(shí)加載多個(gè)文件系統(tǒng),但從外面看起來,只能看到一一個(gè)文件系統(tǒng),聯(lián)合加載會(huì)把各層文件系統(tǒng)疊加起來,這樣最終的文件系統(tǒng)會(huì)包含所有底層的文件和目錄。我們下載的時(shí)候看到的一層層的就是聯(lián)合文件系統(tǒng)。
?
鏡像加載原理?
Docker的鏡像實(shí)際上由一層一層的文件系統(tǒng)組成,這種層級(jí)的文件系統(tǒng)就是UnionFS。
bootfs主要包含bootloader和kernel,bootloader主 要是引導(dǎo)加載kernel,Linux剛啟 動(dòng)時(shí)會(huì)加載bootfs文件系統(tǒng)。
在Docker鏡像的最底層是bootfs,這一層 與我們典型的Linux/Unix系統(tǒng)是一樣的, 包含boot加載器和內(nèi)核。當(dāng)boot加載完成之 后整個(gè)內(nèi)核就都在內(nèi)存中了,此時(shí)內(nèi)存的使用權(quán)已由bootfs轉(zhuǎn)交給內(nèi)核,此時(shí)系統(tǒng)也會(huì)卸載bootfs。
rootfs,在bootfs之 上。包含的就是典型Linux系統(tǒng)中的/dev、/proc、/bin、/etc等標(biāo)準(zhǔn)目錄和文件。rootfs就是各種不同的操作系統(tǒng)發(fā)行版,比如Ubuntu, Centos等。
bootfs就是內(nèi)核引導(dǎo)器(引導(dǎo)加載內(nèi)核)和內(nèi)核。
rootfs是n多個(gè)基礎(chǔ)鏡像(提供基礎(chǔ)操作環(huán)境)和應(yīng)用鏡像疊加在一起的只讀層。
運(yùn)行的容器實(shí)例會(huì)在rootfs之上添加一個(gè)可讀可寫層。
?
容器中操作系統(tǒng)容量小的原因?
因?yàn)閷?duì)于精簡(jiǎn)的OS,rootfs可以很小, 只需要包含最基本的命令、工具和程序庫就可以了,因?yàn)榈讓又苯佑盟拗鳈C(jī)的kernel,自己只需要提供rootfs就可以了。由此可見對(duì)于不同的linux發(fā)行版,bootfs基本是一 致的, rootfs會(huì) 有差別,因此不同的發(fā)行版可以公用bootfs。
大部分鏡像是通用的,但如果專門基于某個(gè)版本創(chuàng)建的鏡像,在其他版本的操作系統(tǒng)中運(yùn)行可能會(huì)有問題。
Docker鏡像結(jié)構(gòu)的分層
鏡像不是一個(gè)單一的文件,而是有多層構(gòu)成。容器其實(shí)是在鏡像的最上面加了一層讀寫層,在運(yùn)行容器里做的任何文件改動(dòng),都會(huì)寫到這個(gè)讀寫層。如果刪除了容器,也就刪除了其最上面的讀寫層,文件改動(dòng)也就丟失了。Docker使用存儲(chǔ)驅(qū)動(dòng)管理鏡像每層內(nèi)容及可讀寫層的容器層。
(1)Dockerfile中的每個(gè)指令都會(huì)創(chuàng)建一個(gè)新的鏡像層;
(2)鏡像層將被緩存和復(fù)用;
(3)當(dāng)Dockerfile的指令修改了,復(fù)制的文件變化了,或者構(gòu)建鏡像時(shí)指定的變量不同了,對(duì)應(yīng)的鏡像層緩存就會(huì)失效;
(4)某一層的鏡像緩存失效,它之后的鏡像層緩存都會(huì)失效;
(5)鏡像層是不可變的,如果在某一層中添加一個(gè)文件,然后在下一層中刪除它,則鏡像中依然會(huì)包含該文件,只是這個(gè)文件在Docker 容器中不可見了。
?
Dockefile的引入
Docker鏡像是一個(gè)特殊的文件系統(tǒng),除了提供容器運(yùn)行時(shí)所需的程序、庫、資源、配置等文件外,還包含了一些為運(yùn)行時(shí)準(zhǔn)備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等)。鏡像不包含任何動(dòng)態(tài)數(shù)據(jù),其內(nèi)容在構(gòu)建之后也不會(huì)被改變。?
鏡像的定制實(shí)際上就是定制每一層所添加的配置、文件。如果我們可以把每一層修改 安裝、構(gòu)建、操作的命令都寫入一個(gè)腳本, 用這個(gè)腳本來構(gòu)建、定制鏡像,那么鏡像構(gòu)建透明性的問題、體積的問題就都會(huì)解決。這個(gè)腳本就是Dockerfile。
我們需要定制首己額外的需求時(shí),只需在Docketlle上添加或者修改指令,重新生成image 即可,省去了敲命令的麻煩。就是描述該層應(yīng)當(dāng)如何構(gòu)建。有了Dockerfile,當(dāng)我們需要定制自己額外的需求時(shí),只需在Dockerfile上添加或者修改指令,重新生成image即可,省去了敲命令的麻煩。
除了手動(dòng)生成Docker鏡像之外,可以使用bockerfile自動(dòng)生成鏡像。Dockerfile 是由多條的指令組成的文件,其中每條指令對(duì)應(yīng)Linux中的一條命令,Docker程序?qū)⒆x取Dockerfile中的指令生成指定鏡像。
Dockerfile結(jié)構(gòu)大致分為四個(gè)部分:基礎(chǔ)鏡像信息、維護(hù)者信息、鏡像操作指令和容器啟動(dòng)時(shí)執(zhí)行指令。Dockerfile每行支持一 條指令, 每條指令可攜帶多個(gè)參數(shù),支持使用以“#“號(hào)開頭的注釋。
?
?2.?Dockerfile 操作命令的指令
Docker?le簡(jiǎn)介:
Docker?le其實(shí)就是我們用來構(gòu)建Docker鏡像的源碼,當(dāng)然這不是所謂的編程源碼,而是一些命令的組合,只要理解它的邏輯和語法格式,就可以編寫Docker?le了。
簡(jiǎn)單點(diǎn)說,Docker?le的作用:它可以讓用戶個(gè)性化定制Docker鏡像。因?yàn)楣ぷ鳝h(huán)境中的需求各式各樣,網(wǎng)絡(luò)上的鏡像很難滿足實(shí)際的需求。
Docker?le常見命令:?
2.1 FROM 鏡像
指定新鏡像所基于的基礎(chǔ)鏡像,第一條指令必須為FROM指令,每創(chuàng)建一-個(gè)鏡像就需要一條FROM指令。
2.2 MAINTAINER 名字
說明新鏡像的維護(hù)人信息
2.3 RUN 命令
在所基于的鏡像上執(zhí)行命令,并提交到新的鏡像中.
盡量減少run命令的條數(shù)。
? ? ? 當(dāng)命令較長(zhǎng)時(shí),可以使用 \ 來換行;
? ? ? 多條命令可以使用 ; 或 && 合并成一條命令,減少鏡像的層數(shù)。
?
2.4 ENTRYPOINT
ENTRYPOINT ["要運(yùn)行的程序","參數(shù)1","參數(shù)2"]
設(shè)定容器啟動(dòng)時(shí)第一個(gè)運(yùn)行的命令及其參數(shù)。
可以通過使用命令?docker run --entrypoint
?來覆蓋鏡像中的ENTRYPOINT指令的內(nèi)容。
?兩種格式:
??
?exec格式(數(shù)值格式):ENTRYPOINT [“命令”,“選項(xiàng)”,“參數(shù)”]
??
?shell格式:ENTRYPOINT 命令 選項(xiàng) 參數(shù)
復(fù)制代碼
2.5 CMD
CMD ["要運(yùn)行的程序","參數(shù)1","參數(shù)2"]
啟動(dòng)容器時(shí)默認(rèn)執(zhí)行的命令或者腳本,Dockerfile只能有一條CMD命令。如果指定多條命令,只執(zhí)行最后一 條命令。
如果在docker run時(shí)指定了命令或者鏡像中有ENTRYPOINT,那么CMD就會(huì)被覆蓋。
CMD 可以為ENTRYPOINT 指令提供默認(rèn)參數(shù)。
?
?兩種格式:
??
?exec形式:CMD [“要運(yùn)行的程序”,“參數(shù)1”, “參數(shù)2”]
??
?shell形式: CMD 命令 參數(shù)1 參數(shù)2
?
ENTRYPOINT和CMD共存的情形:?ENTRYPOIN指定命令,CMD傳參
容器運(yùn)行時(shí)的優(yōu)先級(jí):
docker run --entrypoint > Dockerfile ENTRYPOINT > docker run命令> Dockerfile CMD
ENTRYPOINT和CMD的區(qū)別:
ENTRYPOINT設(shè)定容器啟動(dòng)時(shí)第一個(gè)運(yùn)行的命令;CMD是啟動(dòng)容器時(shí)默認(rèn)執(zhí)行的命令,如果指定多條CMD命令,只執(zhí)行最后一 條命令。
如果在docker run時(shí)指定了命令或者鏡像中有ENTRYPOINT,那么CMD就會(huì)被覆蓋,并且會(huì)將CMD中的命令作為參數(shù)傳給ENTRYPOINT。
CMD可以為ENTRYPOINT進(jìn)行傳參。
?
2.6 EXPOSE 端口號(hào)
指定新鏡像加載到Docker 時(shí)要開啟的端口。
用于暴露端口,否則即使做了端口映射,外部也找不到。
2.7 ENV
ENV 環(huán)境變量 變量值
設(shè)置一個(gè)環(huán)境變量的值,會(huì)被后面的RUN使用。
2.8 ADD
ADD 源文件/目錄 目標(biāo)文件/目錄
將源文件復(fù)制到鏡像的指定路徑中,源文件要與 Dockerfile 位于相同目錄中,或者是一個(gè)URL。(URL路徑,在線路徑)
有如下注意事項(xiàng)
1、
如果源路徑是個(gè)文件,且目標(biāo)路徑是以 / 結(jié)尾, 則docker會(huì)把目標(biāo)路徑當(dāng)作一個(gè)目錄,會(huì)把
源文件拷貝到該目錄下。
如果目標(biāo)路徑不存在,則會(huì)自動(dòng)創(chuàng)建目標(biāo)路徑。
?
2、
如果源路徑是個(gè)文件,且目標(biāo)路徑是不以/結(jié)尾,則docker會(huì)把目標(biāo)路徑當(dāng)作一個(gè)文件。
如果目標(biāo)路徑不存在,會(huì)以目標(biāo)路徑為名創(chuàng)建一個(gè)文件,內(nèi)容同源文件。
如果目標(biāo)文件是個(gè)存在的文件,會(huì)用源文件覆蓋它,當(dāng)然只是內(nèi)容覆蓋,文件名還是目標(biāo)文件名。
如果目標(biāo)文件實(shí)際是個(gè)存在的目錄,則會(huì)源文件拷貝到該目錄下。注意, 這種情況下,最好顯示的
以/結(jié)尾,以避免混淆。
?
3、
如果源路徑是個(gè)目錄,且目標(biāo)路徑不存在,則docker會(huì)自動(dòng)以目標(biāo)路徑創(chuàng)建一個(gè)目錄,把源路徑目錄下
的文件拷貝進(jìn)來。
如果目標(biāo)路徑是個(gè)已經(jīng)存在的目錄,則docker 會(huì)把源路徑目錄下的文件拷貝到該目錄下。
?
4、
如果源文件是個(gè)歸檔文件,則docker會(huì)自動(dòng)幫解壓。(解壓后復(fù)制源目錄到鏡像中的目錄)
URL下載和解壓特性不能一起使用。任何壓縮文件通過URL拷貝,都不會(huì)自動(dòng)解壓。
(不支持下載和解壓一起使用,下載就不會(huì)解壓。即只解壓本地壓縮包,不會(huì)解壓下載的壓縮包)
復(fù)制代碼
ADD 的優(yōu)點(diǎn): 在執(zhí)行 <源文件> 為 tar 壓縮文件的話,壓縮格式為 gzip、bzip2 以及 xz 的情況下,會(huì)自動(dòng)復(fù)制并解壓到 <目標(biāo)路徑>。
ADD 的缺點(diǎn): 在不解壓的前提下,無法復(fù)制 tar 壓縮文件。會(huì)令鏡像構(gòu)建緩存失效,從而可能會(huì)令鏡像構(gòu)建變得比較緩慢。具體是否使用,可以根據(jù)是否需要自動(dòng)解壓來決定。
?
2.9 COPY
COPY 源文件/目錄 目標(biāo)文件/目錄
只復(fù)制本地主機(jī)上的文件/目錄復(fù)制到目標(biāo)地點(diǎn),源文件/目錄要與Dockerfile在相同的目錄中。
ADD和COPY比較:(同樣需求下,官方推薦使用 COPY)
1、共同點(diǎn):
ADD和COPY都可以復(fù)制本地文件到鏡像中。
2、區(qū)別:
ADD:如果是一個(gè)壓縮文件,ADD會(huì)在復(fù)制后自動(dòng)解壓。且支持URL路徑下載源文件,但URL下載和解壓特性不能一起使用,任何壓縮文件通過URL拷貝,都不會(huì)自動(dòng)解壓。
COPY:如果是壓縮文件,COPY并不能解壓。且COPY只能復(fù)制本地文件,不支持URL路徑拷貝。
?
2.10 VOLUME ["目錄"]
在容器中創(chuàng)建一個(gè)掛載點(diǎn)(即創(chuàng)建數(shù)據(jù)卷)。
2.11 USER 用戶名/UID
指定運(yùn)行容器時(shí)的用戶。(用于切換用戶)
2.12 WORKDIR 路徑
為后續(xù)的RUN、CMD、ENTRYPOINT 指定工作目錄。(用于切換容器中的目錄)
CMD 可以為ENTRYPOINT 指令提供默認(rèn)參數(shù)。
?
?workdir /opt ?#切換鏡像層
??
?run cd /opt ? #會(huì)添加鏡像層
2.13 ONBUILD 命令
指定所生成的鏡像作為一個(gè)基礎(chǔ)鏡像時(shí)所要運(yùn)行的命令。
當(dāng)在一個(gè)Dockerfile文件中加上ONBUILD指令,該指令對(duì)利用該Dockerfile構(gòu)建鏡像(比如為A鏡像)不會(huì)產(chǎn)生實(shí)質(zhì)性影響。
但是當(dāng)編寫一個(gè)新的Dockerfile文件來基于A鏡像構(gòu)建一個(gè)鏡像 (比如為B鏡像)時(shí),這時(shí)構(gòu)造A鏡像的Dockerfile文件中的ONBUILD指令就生效了,在構(gòu)建B鏡像的過程中,首先會(huì)執(zhí)行ONBUILD指令指定的指令,然后才會(huì)執(zhí)行其它指令。
(即加私貨,這個(gè)命令不是給我用的,是給其他鏡像用的)
2.14 AG
設(shè)置編譯鏡像時(shí)加入的參數(shù)。
ARG指令,可以引用在docker build構(gòu)建鏡像時(shí)指定的參數(shù),即達(dá)到引用參數(shù)的效果。
使用ENV指令定義的環(huán)境變量始終會(huì)覆蓋同名的ARG指令。
?
?ARG CONT_IMG_VER ? ? ?#Dockfile中指定變量名?
??
?ENV CONT_IMG_VER=v1.0.0?
??
?RUN echo $CONT_IMG_VER ?#AEG和ENV定義的變量名,不要重復(fù),不然最后echo的是ENV定義的值
??
?docker build --build-arg CONT_IMG_VER=v2.0 . ? ? #構(gòu)建鏡像時(shí)傳入變量值
??
?#因?yàn)锳EG和ENV定義的變量名重復(fù)了,ENV指令定義的環(huán)境變量始終會(huì)覆蓋同名的ARG指令,所以最后輸出的是ENV定義的值。
?
2.15 創(chuàng)建鏡像
編寫完成Dockerfile之后,可以通過 docker build 命令來創(chuàng)建鏡像。
基本的格式為 docker build [選項(xiàng)] 路徑,該命令將讀取指定路徑下(包括子目錄)的Dockerfile,并將該路徑下所有內(nèi)容發(fā)送給Docker服務(wù)端,由服務(wù)端來創(chuàng)建鏡像。因此一般建議放置Dockerfile的目錄為空目錄。
另外,可以通過.dockerignore文件(每一行添加一條匹配模式)來讓Docker忽略路徑下的目錄和文件。
要指定鏡像的標(biāo)簽信息,可以通過-t選項(xiàng)。
?
在編寫Dockerfile 時(shí),有嚴(yán)格的格式需要遵循:
第一行必須使用FROM指令指明所基于的鏡像名稱;
之后使用MAINTAINER 指令說明維護(hù)該鏡像的用戶信息;
然后是鏡像操作相關(guān)指令,如RUN指令/EXPOSE/ADD/ENV/ARG等等。每運(yùn)行一條指令,都會(huì)給基礎(chǔ)鏡像添加新的一層。(多條命令可以使用 ; 或 && 合并成一條命令,減少鏡像的層數(shù))
最后使用CMD或者ENTRYPOINT指令指定啟動(dòng)容器時(shí)要運(yùn)行的命令操作。
?
3. Dockefile的實(shí)際運(yùn)用
1? ?dockerfile? yum 安裝apache
#建立工作目錄
mkdir ?/opt/apache
cd ?/opt/apache
?
vim Dockerfile
#基于的基礎(chǔ)鏡像
FROM centos:7
#維護(hù)鏡像的用戶信息
MAINTAINER this is apache image <hmj>
#鏡像操作指令安裝apache軟件
RUN yum -y update
RUN yum -y install httpd
#開啟 80 端口
EXPOSE 80
#復(fù)制網(wǎng)站首頁文件
ADD index.html /var/www/html/index.html
ENTRYPOINT [ "/usr/sbin/apachectl" ]
CMD ["-D", "FOREGROUND"]
?
//準(zhǔn)備網(wǎng)站頁面
echo "this is test web" > index.html
//生成鏡像
docker build -t httpd:centos . ? ?? ??? ?#注意別忘了末尾有"."
?//新鏡像運(yùn)行容器
docker run -d -p 1216:80 httpd:centos
?//測(cè)試
http://192.168.50.24:1216/
?
3.2 實(shí)戰(zhàn)運(yùn)用——Dockfile源碼編譯apache?
vim Dockerfile
?
#基礎(chǔ)鏡像的指定
FROM centos:7
#作者信息
MAINTAINER this is my ?diy apache <xx-2022-11-24>
RUN yum install -y gcc gcc-c++ make pcre pcre-devel expat-devel perl
ADD apr-1.6.2.tar.gz /opt/
ADD apr-util-1.6.0.tar.gz /opt/
ADD httpd-2.4.29.tar.bz2 /opt/
RUN mv /opt/apr-1.6.2 /opt/httpd-2.4.29/srclib/apr && mv /opt/apr-util-1.6.0 /opt/httpd-2.4.29/srclib/apr-util &&\
cd /opt/httpd-2.4.29/ &&\
./configure --prefix=/usr/local/httpd --enable-so --enable-rewrite --enable-charset-lite --enable-cgi &&\
?make -j 4 && make install
?
EXPOSE 80
CMD ["/usr/local/httpd/bin/apachectl","-D","FOREGRUOND"]
?
?
docker build -t apache:centos .? 命令行尾有點(diǎn)
案例3: 編譯安裝nginx
mkdir /opt/nginx
cd /opt/nginx/
cp /opt/nginx-1.12.0.tar.gz /opt/nginxvim Dockerfile
#基于基礎(chǔ)鏡像
FROM centos:7
#用戶信息
MAINTAINER this is nginx image <wl>
#添加環(huán)境包
RUN yum -y update
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
#上傳nginx軟件壓縮包,并解壓
ADD nginx-1.22.0.tar.gz /opt/
#指定工作目錄
WORKDIR /opt/nginx-1.22.0
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
#指定http和https端口
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf?? ??? ??? ?#關(guān)閉 nginx 在后臺(tái)運(yùn)行
#添加宿主機(jī)中run.sh到容器中
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
#CMD ["/usr/local/sbin/nginx", "-g", "daemon off;"]
?案例四? 構(gòu)建lnmp
#部署nginx(容器IP 為 172.18.0.10)
mkdir /opt/nginx
cd /opt/nginx/
上傳 nginx-1.12.0.tar.gz、wordpress-4.9.4-zh_CN.tar.gz 到 /opt/nginx/ 目錄中
mkdir /opt/nginx/html
tar zxvf wordpress-4.9.4-zh_CN.tar.gz -C /opt/nginx/html
vim Dockerfile
FROM centos:7
MAINTAINER this is nginx image <wl>
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.0.tar.gz /usr/local/src/
WORKDIR /usr/local/src/nginx-1.12.0
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
ADD nginx.conf /usr/local/nginx/conf/
#ADD wordpress-4.9.4-zh_CN.tar.gz /usr/local/nginx/html/
RUN chmod 777 -R /usr/local/nginx/html/
EXPOSE 80
EXPOSE 443
ENTRYPOINT [ "/usr/local/nginx/sbin/nginx", "-g", "daemon off;" ]
#部署mysql(容器IP 為 172.18.0.20)
mkdir /opt/mysqld
cd /opt/mysqld
上傳 mysql-boost-5.7.20.tar.gz 到 /opt/mysqld 目錄中
vim Dockerfile
FROM centos:7
MAINTAINER this is mysql image <wl>
RUN yum -y install gcc gcc-c++ ncurses ncurses-devel bison cmake make
ADD mysql-boost-5.7.20.tar.gz /usr/local/src/
WORKDIR /usr/local/src/mysql-5.7.20/
RUN cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 ?\
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=boost \
-DWITH_SYSTEMD=1 && make && make install
ADD my.cnf /etc/
ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
RUN useradd -M -s /sbin/nologin ?mysql
RUN chown mysql:mysql /etc/my.cnf
RUN chown -R mysql:mysql /usr/local/mysql/
RUN /usr/local/mysql/bin/mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
EXPOSE 3306
CMD ["/usr/local/mysql/bin/mysqld"]
vim my.cnf
[client]
port = 3306
socket = /usr/local/mysql/mysql.sock
[mysql]
port = 3306
socket = /usr/local/mysql/mysql.sock
[mysqld]
user = mysql
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
character_set_server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket = /usr/local/mysql/mysql.sock
server-id = 1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
docker build -t mysql:lnmp .
docker run --name=mysql -d --privileged -v /usr/local/mysql --net mynetwork --ip 172.18.0.20 mysql:lnmp
#部署php(容器IP 為 172.18.0.30)
mkdir /opt/php
cd /opt/php
上傳 php-7.1.10.tar.bz2 到 /opt/php 目錄中
vim Dockerfile
FROM centos:7
MAINTAINER this is php image <wl>
RUN yum -y install gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel \
gcc gcc-c++ make pcre-devel?
RUN useradd -M -s /sbin/nologin nginx
ADD php-7.1.10.tar.bz2 /usr/local/src/
WORKDIR /usr/local/src/php-7.1.10
RUN ./configure \
--prefix=/usr/local/php \
--with-mysql-sock=/usr/local/mysql/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-fpm \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip && make && make install
ENV PATH /usr/local/php/bin:/usr/local/php/sbin:$PATH
ADD php.ini?? ?/usr/local/php/lib/
ADD php-fpm.conf /usr/local/php/etc/
ADD www.conf /usr/local/php/etc/php-fpm.d/
EXPOSE 9000
ENTRYPOINT [ "/usr/local/php/sbin/php-fpm", "-F" ]
?
?
?
案例五 tomcat 鏡像
mkdir /opt/tomcat
cd /opt/tomcat
cp /opt/jdk-8u91-linux-x64.tar.gz /opt/tomcat
cp /opt/apache-tomcat-8.5.16.tar.gz /opt/tomcatvim Dockerfile
FROM centos:7
MAINTAINER this is tomcat image <wl>
ADD jdk-8u91-linux-x64.tar.gz /usr/local/
WORKDIR /usr/local/
RUN mv jdk1.8.0_91 /usr/local/java
ENV JAVA_HOME /usr/local/java
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH $JAVA_HOME/bin:$PATH
ADD apache-tomcat-8.5.16.tar.gz /usr/local/
WORKDIR /usr/local/
RUN mv apache-tomcat-8.5.16 /usr/local/tomcat
EXPOSE 8080
#CMD ["/usr/local/tomcat/bin/catalina.sh","run"]
ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
//創(chuàng)建新鏡像
docker build -t tomcat:centos .docker run -d --name tomcat01 -p 1216:8080 tomcat:centos?
?
http://192.168.50.24:1216
?
Dockerfile 多階段構(gòu)建原理和使用場(chǎng)景
多個(gè) FROM 指令的意義
多個(gè)?FROM
?指令并不是為了生成多根的層關(guān)系,最后生成的鏡像,仍以最后一條?FROM
?為準(zhǔn),之前的?FROM
?會(huì)被拋棄,那么之前的FROM
?又有什么意義呢?
每一條?FROM
?指令都是一個(gè)構(gòu)建階段,多條?FROM
?就是多階段構(gòu)建,雖然最后生成的鏡像只能是最后一個(gè)階段的結(jié)果,但是,能夠?qū)⑶爸秒A段中的文件拷貝到后邊的階段中,這就是多階段構(gòu)建的最大意義。
最大的使用場(chǎng)景是將編譯環(huán)境和運(yùn)行環(huán)境分離,比如,之前我們需要構(gòu)建一個(gè)Go語言程序,那么就需要用到go命令等編譯環(huán)境,我們的Dockerfile可能是這樣的:
# 編譯階段
FROM golang:1.10.3COPY server.go /build/
WORKDIR /build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOARM=6 go build -ldflags '-w -s' -o server
# 運(yùn)行階段
?FROM scratch# 從編譯階段的中拷貝編譯結(jié)果到當(dāng)前鏡像中
COPY --from=0 /build/server /ENTRYPOINT ["/server"]
這個(gè) Dockerfile 的玄妙之處就在于 COPY 指令的--from=0
?參數(shù),從前邊的階段中拷貝文件到當(dāng)前階段中,多個(gè)FROM
語句時(shí),0代表第一個(gè)階段。除了使用數(shù)字,我們還可以給階段命名,比如:
# 編譯階段 命名為 builder
FROM golang:1.10.3 as builder# ... 省略
# 運(yùn)行階段
FROM scratch文章來源:http://www.zghlxwxcb.cn/news/detail-652745.html# 從編譯階段的中拷貝編譯結(jié)果到當(dāng)前鏡像中
COPY --from=builder /build/server /文章來源地址http://www.zghlxwxcb.cn/news/detail-652745.html
到了這里,關(guān)于【云原生】Docker鏡像的創(chuàng)建 Dockerfile 多階段構(gòu)建原理和使用場(chǎng)景的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!