如何用Dockerfile構(gòu)建鏡像

如何用Dockerfile構(gòu)建鏡像

本文旨在用通俗的語言講述枯燥的知識

前面講到鏡像的構(gòu)建時,講述的是用commit的方式構(gòu)建鏡像,而Dockerfile是另一種構(gòu)建鏡像的方式。

Dockerfile構(gòu)建鏡像是以基礎(chǔ)鏡像為基礎(chǔ)的,Dockerfile是一個文本文件,內(nèi)容是用戶編寫的一些docker指令,每一條指令構(gòu)建一層,因此每一條指令的內(nèi)容,就是描述該層應(yīng)當(dāng)如何構(gòu)建。

Dockerfile的基本指令有十三個,分別是:FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD

從前面的內(nèi)容可以看出,要構(gòu)建一個容器,需要做很多的工作,設(shè)置很多的配置,如果我們可以把每一層修改、安裝、構(gòu)建、操作的命令都寫入一個腳本,用這個腳本來構(gòu)建、定制鏡像,那么之前提及的無法重復(fù)的問題、鏡像構(gòu)建透明性的問題、體積的問題就都會解決。

這個腳本就是 Dockerfile。

因此學(xué)會用Dockerfile來構(gòu)建鏡像,是非常有必要的。學(xué)習(xí)Dockerfile之前,我們先來學(xué)習(xí)一些Dockerfile常用的指令。

文章提綱:

Dockerfile常用指令

Dockerfile的編寫

用Dockerfile構(gòu)建鏡像

彩蛋

1 Dockerfile常用指令

類型命令

基礎(chǔ)鏡像信息FROM

維護(hù)者信息MAINTAINER

鏡像操作指令RUN、COPY、ADD、EXPOSE、WORKDIR、ONBUILD、USER、VOLUME等

容器啟動時執(zhí)行指令CMD、ENTRYPOINT

1.1、FROM :指定基礎(chǔ)鏡像

所謂定制鏡像,那一定是以一個鏡像為基礎(chǔ),在其上進(jìn)行定制。就像我們之前運行了一個nginx鏡像的容器,再進(jìn)行修改一樣,基礎(chǔ)鏡像是必須指定的。而FROM就是指定基礎(chǔ)鏡 像,因此一個Dockerfile中FROM是必備的指令,并且必須是第一條指令。

如:指定ubuntu的14版本作為基礎(chǔ)鏡像

FROM ubuntu:14

1.2、 RUN:執(zhí)行命令

RUN指令在新鏡像內(nèi)部執(zhí)行的命令,如:執(zhí)行某些動作、安裝系統(tǒng)軟件、配置系統(tǒng)信息之類,

格式如下兩種:

1)shell格式:RUN< command > ,就像直接在命令行中輸入的命令一樣。

如在nginx里的默認(rèn)主頁中寫”hello“:

RUN echo 'hello ' >/etc/nginx/html/index.html

2)exec格式:RUN ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"]

如在新鏡像中用yum方式安裝nginx:

RUN ["yum","install","nginx"]

注:多行命令不要寫多個RUN,原因是Dockerfile中每一個指令都會建立一層.多少個RUN就構(gòu)建了多少層鏡像,會造成鏡像的臃腫、多層,不僅僅增加了構(gòu)件部署的時間,還容易出錯,RUN書寫時的換行符是\

1.3、COPY:復(fù)制文件

COPY命令用于將宿主機(jī)器上的的文件復(fù)制到鏡像內(nèi),如果目的位置不存在,Docker會自動創(chuàng)建。但宿主機(jī)器用要復(fù)制的目錄必須是和Dockerfile文件統(tǒng)計目錄下。

格式:

COPY [--chown=<user>:<group>]<源路徑>...<目標(biāo)路徑>COPY [--chown=<user>:<group>] ["<源路徑1>",... "<目標(biāo)路徑>"]

如把宿主機(jī)中的package.json文件復(fù)制到容器中/usr/src/app/目錄下:

COPY package.json /usr/src/app/

1.4、CMD:容器啟動命令

CMD命令用于容器啟動時需要執(zhí)行的命令,CMD在Dockerfile中只能出現(xiàn)一次,如果出現(xiàn)多個,那么只有最后一個會有效。

其作用是在啟動容器的時候提供一個默認(rèn)的命令項。如果用戶執(zhí)行docker run的時候提供了命令項,就會覆蓋掉這個命令,沒提供就會使用構(gòu)建時的命令。

格式:

shell 格式:CMD<命令>exec 格式:CMD ["可執(zhí)行文件", "參數(shù)1", "參數(shù)2"...]

如容器啟動時進(jìn)入bash:

CMD /bin/bash

也可以用exec寫法:

CMD ["/bin/bash"]

1.5 MAINTAINER:指定作者

用來指定dockerfile的作者名稱和郵箱,主要作用是為了標(biāo)識軟件的所有者是誰。

語法:

MAINTAINER<name><email>

如:

MAINTAINER autor_jiabuli 6766633@qq.com

1.6、EXPOSE:暴露端口

EXPOSE命名適用于設(shè)置容器對外映射的容器端口號,如tomcat容器內(nèi)使用的端口8081,則用EXPOSE命令可以告訴外界該容器的8081端口對外,在構(gòu)建鏡像時

用docker run -p可以設(shè)置暴露的端口對宿主機(jī)器端口的映射。

語法:

EXPOSE<端口1>[<端口2>...]

如:

EXPOSE 8081

EXPOSE 8081 其實等價于 docker run -p 8081 當(dāng)需要把8081端口映射到宿主機(jī)中的某個端口(如8888)以便外界訪問時,則可以用docker run -p 8888:8081

1.7、WORKDIR:配置工作目錄

WORKDIR命令是為RUN、CMD、ENTRYPOINT指令配置工作目錄。其效果類似于Linux命名中的cd命令,用于目錄的切換,但是和cd不一樣的是:如果切換到的目錄不存在,WORKDIR會為此創(chuàng)建目錄。

語法:

WORKDIR path

如需要在nginx目錄下創(chuàng)建一個hello.txt的文件:

##進(jìn)入/usr/local/nginx目錄下

WORKDIR /usr/local/nginx

##進(jìn)入/usr/local/nginx中的html目錄下

WORKDIR html

## 在html目錄下創(chuàng)建了一個hello.txt文件

RUN echo 'hello' > hello.txt

1.8、ENTRYPOINT:容器啟動執(zhí)行命名

ENTRYPOINT的作用和用法和CMD一模一樣,但是ENTRYPOINT有和CMD有2處不一樣:

CMD的命令會被docker run的命令覆蓋而ENTRYPOINT不會

CMD和ENTRYPOINT都存在時,CMD的指令變成了ENTRYPOINT的參數(shù),并且此CMD提供的參數(shù)會被 docker run 后面的命令覆蓋

1.9、VOLUME

VOLUME用來創(chuàng)建一個可以從本地主機(jī)或其他容器掛載的掛載點。例如我們知道tomcat的webapps目錄是放web應(yīng)用程序代碼的地方,此時我們要把webapps目錄掛載為匿名卷,這樣任何寫入webapps中的心都不會被記錄到容器的存儲層,讓容器存儲層無狀態(tài)化。

格式:

VOLUME ["path"]

如創(chuàng)建tomcat的webapps目錄的一個掛載點

VOLUME /usr/local/tomcat/webapps

這樣,在運行容器時,也可以用過docker run -v來把匿名掛載點掛載都宿主機(jī)器上的某個目錄,如

docker run -d -v /home/tomcat_webapps:/usr/local/tomcat/webapps

1.10、 USER

USER命令用于指定當(dāng)前望下執(zhí)行的用戶,需要注意的是這個用戶必須是已經(jīng)存在,否則無法指定。它的用法和WORKDIR有點像,切換用戶。

格式:

USER daemon

1.11、ADD

作用和使用方法和COPY一模一樣,在此不重復(fù)講述。

1.12、ONBUILD

ONBUILD用于配置當(dāng)前所創(chuàng)建的鏡像作為其它新創(chuàng)建鏡像的基礎(chǔ)鏡像時,所執(zhí)行的操作指令。

意思就是:這個鏡像創(chuàng)建后,如果其它鏡像以這個鏡像為基礎(chǔ),會先執(zhí)行這個鏡像的ONBUILD命令

格式:

ONBUILD [INSTRUCTION]

1.13、ENV:設(shè)置環(huán)境變量

ENV命名用于設(shè)置容器的環(huán)境變量,這些變量以”key=value”的形式存在,在容器內(nèi)被腳本或者程序調(diào)用,容器運行的時候這個變量也會保留。

格式:

1) 設(shè)置一個: ENV <key> <value>

2) 設(shè)置多個:ENV <key1>=<value1> <key2>=<value2>...

如設(shè)置一個環(huán)境變量JAVA_HOME,接下來的命名就可以使用這個變量:

ENV JAVA_HOME /opt/jdk

ENV PATH $PATH:$JAVA_HOME/bin

在使用ENV設(shè)置環(huán)境變量時,有幾點需要注意:

1)具有傳遞性,也就是當(dāng)前鏡像被用作其它鏡像的基礎(chǔ)鏡像時,新鏡像會擁有當(dāng)前這個基礎(chǔ)鏡像所有的環(huán)境變量

2)ENV定義的環(huán)境變量,可以在dockerfile被后面的所有指令(CMD除外)中使用,但不能被docker run 的命令參數(shù)引用

如:

ENV tomcat_home_name tomcat_7

RUN mkdir $tomcat_home_name

3)除了ENV之外,docker run -e 也可以設(shè)置環(huán)境變量傳入容器內(nèi)。

如:

docker run -d tomcat -e "tomcat_home_name=tomcat_7"

這樣我們進(jìn)入容器內(nèi)部用ENV可以看到tomcat_home_name這個環(huán)境變量。

2 Dockerfile的編寫

我們先看一個例子

#在centos上安裝nginx

FROM centos

#標(biāo)明著作人的名稱和郵箱

MAINTAINER jiabuli 649917837@qq.com

#測試一下網(wǎng)絡(luò)環(huán)境

RUN ping -c 1 www.baidu.com

#安裝nginx必要的一些軟件

RUN yum -y install gcc make pcre-devel zlib-devel tar zlib

#把nginx安裝包復(fù)制到/usr/src/目錄下

ADD nginx-1.15.8.tar.gz /usr/src/

#切換到/usr/src/nginx-1.15.8編譯并且安裝nginx

RUN cd /usr/src/nginx-1.15.8 \

? ? && mkdir /usr/local/nginx \

? ? && ./configure --prefix=/usr/local/nginx && make && make install \

? ? && ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ \

? ? && nginx

#刪除安裝nginx安裝目錄

RUN rm -rf /usr/src/nginx-nginx-1.15.8

#對外暴露80端口

EXPOSE 80

#啟動nginx

CMD ["nginx", "-g", "daemon off;"]

上面的注釋已經(jīng)講的非常清楚,其實不難發(fā)現(xiàn),上面的例子就是類似于在centos系統(tǒng)上安裝一個nginx的的一個過程,因此編寫Dockerfile構(gòu)建鏡像就和在Linux上安裝軟件的流程幾乎是一模一樣的。所以我們在編寫Dockerfile來構(gòu)建鏡像時,可以先思考在Linux上安裝該軟件的流程,再用Dockerfile提供的指令轉(zhuǎn)化到Dockerfile中即可。

3.用Dockerfile構(gòu)建鏡像

用Dockerfile的核心在于編寫Dockerfile,但是編寫完之后我們需要知道怎么使用Dockerfile來構(gòu)建鏡像,下面以構(gòu)建nginx鏡像為例來簡要說明構(gòu)建流程

3.1 上傳安裝包

首先我們需要把要構(gòu)建的軟件安裝包上傳到服務(wù)器中,我們可以在服務(wù)器目錄上創(chuàng)建一個專門的文件夾,如:/var/nginx_build,然后把從nginx官網(wǎng)下載的nginx-1.15.8.tar.gz安裝包上傳到這個目錄里。

3.2 編寫Dockerfile

如何編寫nginx的Dockerfile上面已經(jīng)詳細(xì)介紹,現(xiàn)在我們只需把編寫好的Dockerfile上傳到/var/nginx_build目錄下,當(dāng)然你也可以在服務(wù)器上直接編寫Dockerfile,但是要記得一定保證Dockerfile文件和安裝包在一個目錄下。

3.3 運行構(gòu)建命令構(gòu)建

docker build 命令用于使用 Dockerfile 創(chuàng)建鏡像。

格式:

? docker build [OPTIONS] PATH | URL | -

OPTIONS有很多指令,下面列舉幾個常用的:

--build-arg=[] :設(shè)置鏡像創(chuàng)建時的變量;

-f :指定要使用的Dockerfile路徑;

--force-rm :設(shè)置鏡像過程中刪除中間容器;

--rm :設(shè)置鏡像成功后刪除中間容器;

--tag, -t:?鏡像的名字及標(biāo)簽,通常 name:tag 或者 name 格式;

因此我們構(gòu)建nginx可以用以下命令:

docker build -t nginx:v1.0 .

當(dāng)Dockerfile和當(dāng)前執(zhí)行命令的目錄不在同一個時,我們也可以指定Dockerfile,如

docker build -f /var/nginx_build/Dockerfile .

執(zhí)行命名之后,會看到控制臺逐層輸出構(gòu)建內(nèi)容,直到輸出兩個Successfully即為構(gòu)建成功。

4. 彩蛋

寫了很多篇docker的文章,為了方便開發(fā)者們學(xué)習(xí)和查閱docker的基礎(chǔ)知識,我做了一份完整的docker基礎(chǔ)整理,發(fā)布在gitchat上面,有興趣的讀者可以加入一起學(xué)習(xí),我這里還有6個免費名額,如有需要,可以加微信:15601111341 索要。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容