[转]Docker基础-使用Dockerfile创建镜像
本文轉(zhuǎn)自:https://www.cnblogs.com/jie-fang/p/7927643.html
1、基本結(jié)構(gòu)
Dockerfile由一行行命令語句組成,并支持以#開頭的注釋行。例如:
# This dockerfile uses the ubuntu image # VERSION 2 - EDITION 1 # Author: docker_user # Command format: Instruction [arguments / command ] ..# Base image to use, this nust be set as the first line FROM ubuntu# Maintainer: docker_user <docker_user at email.com> (@docker_user) MAINTAINER docker_user docker_user@email.com# Commands to update the image RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list RUN apt-get update && apt-get install -y nginx RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf# Commands when creating a new container CMD /usr/sbin/nginx其中,開始必須指明所基于的鏡像名稱,接下來一般是說明維護(hù)者信息。后面則是鏡像操作指令,例如RUN指令,RUN指令將對(duì)鏡像執(zhí)行跟隨的命令。每運(yùn)行一條RUN指令,鏡像就添加新的一層,并提交。最后是CMD指令,用來指定運(yùn)行容器時(shí)的操作命令。
Docker Hub上兩個(gè)熱門Dockerfile:
1.在debian:jessie基礎(chǔ)鏡像上安裝nginx環(huán)境,從而創(chuàng)建一個(gè)新的nginx鏡像:
FROM debian:jessieMAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com"ENV NGINX_VERSION 1.10.1-1~jessieRUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 && \ echo "deb http://nginx.org/package/debian/ jessie nginx" >> /etc/apt/source.list && apt-get update && \ apt-get install --no-install-recommends --no-install-suggests -y ca-certificates nginx=$(NGINX_VERSION) \ nginx-module-xslt nginx-module-geoip nginx-module-image-filter nginx-module-perl nginx-module-njs gettext-base && \ rm -rf /var/lib/apt/lists/*# forward request and error logs to docker log collector RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/err.logEXPOSE 80 443CMD ["nginx","-g","daemon off;"]2.基于buildpack-deps:jessie-scm基礎(chǔ)鏡像,安裝golang相關(guān)環(huán)境,制作一個(gè)GO語言的運(yùn)行環(huán)境。
FROM buildpack-deps:jessie-scm# gcc fo cgo RUN apt-get update && apt-get install -y --no-install-recommends g++ gcc libc6-dev make && rm -rf /var/lib/apt/lists*ENV GOLANG_VERSION 1.6.3 ENV GOLANG_DOWNLOAD_RUL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz ENV GOLANG_DOWNLOAD_SHA256 cdd5e08530c0579255d6153b08fdb3b8e47caabbe717bc7bcd7561275a87aebRUN curl -fssL "$GOLANG_DOWNLOAD_RUL" -o golang.tar.gz && \ echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - && tar -C /usr/local -xzf golang.tar.gz && rm golang.tar.gzENV GOPATH $GOPATH/bin:/usr/local/go/bin:$PATHRUN mkdir -p "$GOPATH/bin" && chmod -R 777 "$GOPATH" WORKDIR $GOPATHCOPY go-wrapper /usr/local/bin2、指令說明
指令的一般格式為INSTRUNCTION arguments,指令包括FROM、MAINTAINER、RUN等。具體指令及說明如下:
| 指令 | 說明 |
| FROM | 指定所創(chuàng)建鏡像的基礎(chǔ)鏡像 |
| MAINTAINER | 指定維護(hù)者信息 |
| RUN | 運(yùn)行命令 |
| CMD | 指定啟動(dòng)容器時(shí)默認(rèn)執(zhí)行的命令 |
| LABEL | 指定生成鏡像的元數(shù)據(jù)標(biāo)簽信息 |
| EXPOSE | 聲明鏡像內(nèi)服務(wù)所監(jiān)聽的端口 |
| ENV | 指定環(huán)境變量 |
| ADD | 賦值指定的<src>路徑下的內(nèi)容到容器中的<dest>路徑下,<src>可以為URL;如果為tar文件,會(huì)自動(dòng)解壓到<dest>路徑下 |
| COPY | 賦值本地主機(jī)的<scr>路徑下的內(nèi)容到容器中的<dest>路徑下;一般情況下推薦使用COPY而不是ADD |
| ENTRYPOINT | 指定鏡像的默認(rèn)入口 |
| VOLUME | 創(chuàng)建數(shù)據(jù)掛載點(diǎn) |
| USER | 指定運(yùn)行容器時(shí)的用戶名或UID |
| WORKDIR | 配置工作目錄 |
| ARG | 指定鏡像內(nèi)使用的參數(shù)(例如版本號(hào)信息等) |
| ONBUILD | 配置當(dāng)前所創(chuàng)建的鏡像作為其他鏡像的基礎(chǔ)鏡像時(shí),所執(zhí)行的創(chuàng)建操作的命令 |
| STOPSIGNAL | 容器退出的信號(hào) |
| HEALTHCHECK | 如何進(jìn)行健康檢查 |
| SHELL | 指定使用SHELL時(shí)的默認(rèn)SHELL類型 |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
1.FROM
指定所創(chuàng)建的鏡像的基礎(chǔ)鏡像,如果本地不存在,則默認(rèn)會(huì)去Docker Hub下載指定鏡像。
格式為:FROM<image>,或FROM<image>:<tag>,或FROM<image>@<digest>。
任何Dockerfile中的第一條指令必須為FROM指令。并且,如果在同一個(gè)Dockerfile文件中創(chuàng)建多個(gè)鏡像,可以使用多個(gè)FROM指令(每個(gè)鏡像一次)。
2.MAINTAINER
指定維護(hù)者信息,格式為MAINTAINER<name>。例如:
MAINTAINER image_creator@docker.com該信息將會(huì)寫入生成鏡像的Author屬性域中。
3.RUN
運(yùn)行指定命令。
格式為:RUN<command>或RUN ["executable","param1","param2"]。
注意:
?? ?后一個(gè)指令會(huì)被解析為json數(shù)組,所以必須使用雙引號(hào)。
前者默認(rèn)將在shell終端中運(yùn)行命令,即/bin/sh -c;后者則使用exec執(zhí)行,不會(huì)啟動(dòng)shell環(huán)境。
指定使用其他終端類型可以通過第二種方式實(shí)現(xiàn),例如:
?? ?RUN ["/bin/bash","-c","echo hello"]
每條RUN指令將在當(dāng)前鏡像的基礎(chǔ)上執(zhí)行指定命令,并提交為新的鏡像。當(dāng)命令較長時(shí)可以使用\換行。例如:
4.CMD
CMD指令用來指定啟動(dòng)容器時(shí)默認(rèn)執(zhí)行的命令。它支持三種格式:
1.CMD ["executable","param1","param2"] 使用exec執(zhí)行,是推薦使用的方式; 2.CMD param1 param2 在/bin/sh中執(zhí)行,提供給需要交互的應(yīng)用; 3.CMD ["param1","param2"] 提供給ENTRYPOINT的默認(rèn)參數(shù)。每個(gè)Dockerfile只能有一條CMD命令。如果指定了多條命令,只有最后一條會(huì)被執(zhí)行。入股用戶啟動(dòng)容器時(shí)指定了運(yùn)行的命令(作為run的參數(shù)),則會(huì)覆蓋掉CMD指定的命令。
5.LABEL
LABEL指令用來生成用于生成鏡像的元數(shù)據(jù)的標(biāo)簽信息。
格式為:LABEL <key>=<value> <key>=<value> <key>=<value> ...。
例如:
6.EXPOSE
聲明鏡像內(nèi)服務(wù)所監(jiān)聽的端口。
格式為:EXPOSE <port> [<port>...]
例如:
注意:
該命令只是起到聲明租用,并不會(huì)自動(dòng)完成端口映射。
?? ??? 在容器啟動(dòng)時(shí)需要使用-P(大寫P),Docker主機(jī)會(huì)自動(dòng)分配一個(gè)宿主機(jī)未被使用的臨時(shí)端口轉(zhuǎn)發(fā)到指定的端口;使用-p(小寫p),則可以具體指定哪個(gè)宿主機(jī)的本地端口映射過來。
7.ENV
指定環(huán)境變量,在鏡像生成過程中會(huì)被后續(xù)RUN指令使用,在鏡像啟動(dòng)的容器中也會(huì)存在。
格式為:ENV <key><value>或ENV<key>=<value>...。
例如:
指令指定的環(huán)境變量在運(yùn)行時(shí)可以被覆蓋掉,如docker run --env <key>=<value> built_image。
8.ADD
該指令將復(fù)制指定的<src>路徑下的內(nèi)容到容器中的<dest>路徑下。
格式為:ADD<src> <dest>
其中<src>可以使Dockerfile所在目錄的一個(gè)相對(duì)路徑(文件或目錄),也可以是一個(gè)URL,還可以是一個(gè)tar文件(如果是tar文件,會(huì)自動(dòng)解壓到<dest>路徑下)。<dest>可以使鏡像內(nèi)的絕對(duì)路徑,或者相當(dāng)于工作目錄(WORKDIR)的相對(duì)路徑。路徑支持正則表達(dá)式,例如:
9.COPY
復(fù)制本地主機(jī)的<src>(為Dockerfile所在目錄的一個(gè)相對(duì)路徑、文件或目錄)下的內(nèi)容到鏡像中的<dest>下。目標(biāo)路徑不存在時(shí),會(huì)自動(dòng)創(chuàng)建。路徑同樣支持正則。
格式為:COPY <src> <dest>
當(dāng)使用本地目錄為源目錄時(shí),推薦使用COPY。
10.ENTRYPOINT
指定鏡像的默認(rèn)入口命令,該入口命令會(huì)在啟動(dòng)容器時(shí)作為根命令執(zhí)行,所有傳入值作為該命令的參數(shù)。
支持兩種格式:
此時(shí),CMD指令指定值將作為根命令的參數(shù)。
每個(gè)Dockerfile中只能有一個(gè)ENTRYPOINT,當(dāng)指定多個(gè)時(shí),只有最后一個(gè)有效。
在運(yùn)行時(shí)可以被--entrypoint參數(shù)覆蓋掉,如docker run --entrypoint。
11.VOLUME
創(chuàng)建一個(gè)數(shù)據(jù)卷掛載點(diǎn)。
格式為:VOLUME ["/data"]
可以從本地主機(jī)或者其他容器掛載數(shù)據(jù)卷,一般用來存放數(shù)據(jù)庫和需要保存的數(shù)據(jù)等。
12.USER
指定運(yùn)行容器時(shí)的用戶名或UID,后續(xù)的RUN等指令也會(huì)使用特定的用戶身份。
格式為:USER daemon
當(dāng)服務(wù)不需要管理員權(quán)限時(shí),可以通過該指令指定運(yùn)行用戶,并且可以在之前創(chuàng)建所需要的用戶。例如:
要臨時(shí)獲取管理員權(quán)限可以用gosu或者sudo。
13.WORKDIR
為后續(xù)的RUN、CMD和ENTRYPOINT指令配置工作目錄。
格式為:WORKDIR /path/to/workdir。
可以使用多個(gè)WORKDIR指令,后續(xù)命令如果參數(shù)是相對(duì)的,則會(huì)基于之前命令指定的路徑。例如:
則最終路徑為/a/b/c
14.ARG
指定一些鏡像內(nèi)使用的參數(shù)(例如版本號(hào)信息等),這些參數(shù)在執(zhí)行docker build命令時(shí)才以--build-arg<varname>=<value>格式傳入。
格式為:ARG<name>[=<default value>]。
則可以用docker build --build-arg<name>=<value>來指定參數(shù)值。
15.ONBUILD
配置當(dāng)所創(chuàng)建的鏡像作為其他鏡像的基礎(chǔ)鏡像的時(shí)候,所執(zhí)行創(chuàng)建操作指令。
格式為:ONBUILD [INSTRUCTION]。
例如Dockerfile使用如下的內(nèi)容創(chuàng)建了鏡像image-A:
如果基于image-A鏡像創(chuàng)建新的鏡像時(shí),新的Dockerfile中使用FROM image-A指定基礎(chǔ)鏡像,會(huì)自動(dòng)執(zhí)行ONBUILD指令的內(nèi)容,等價(jià)于在后面添加了兩條指令:
FROM image-A# Automatically run the following ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src使用ONBUILD指令的鏡像,推薦在標(biāo)簽中注明,例如:ruby:1.9-onbuild。
16.STOPSIGNAL
指定所創(chuàng)建鏡像啟動(dòng)的容器接收退出的信號(hào)值。例如:
STOPSIGNAL singnal17.HEALTHCHECK
配置所啟動(dòng)容器如何進(jìn)行健康檢查(如何判斷是否健康),自Docker 1.12開始支持。
格式有兩種:
[OPTION]支持:
1.--inerval=DURATION (默認(rèn)為:30s):多久檢查一次; 2.--timeout=DURATION (默認(rèn)為:30s):每次檢查等待結(jié)果的超時(shí)時(shí)間; 3.--retries=N (默認(rèn)為:3):如果失敗了,重試幾次才最終確定失敗。18.SHELL
指定其他命令使用shell時(shí)的默認(rèn)shell類型。
格式為: SHELL ["executable","parameters"]
默認(rèn)值為 ["bin/sh","-c"]。
注意:
對(duì)于Windows系統(tǒng),建議在Dockerfile開頭添加# escape=`來指定轉(zhuǎn)移信息。
?
3、創(chuàng)建鏡像
編寫玩Dockerfile之后,可以通過docker build命令來創(chuàng)建鏡像。
基本的docker build [選項(xiàng)] 內(nèi)容路徑,該命令將讀取指定路徑下(包括子目錄)的Dockerfile,并將該路徑下的所有內(nèi)容發(fā)送給Docker服務(wù)端,由服務(wù)端來創(chuàng)建鏡像。因此除非生成鏡像需要,否則一般建議放置Dockerfile的目錄為空目錄。
例如:指定Dockerfile所在路徑為 /tmp/docker_builder/,并且希望生成鏡像標(biāo)簽為build_repo/first_image,可以使用下面的命令:
docker build -t build_repo/first_image /tmp/docker_builder4、使用 .dockerignore文件
可以通過 .dockeringore文件(每一行添加一條匹配模式)來讓Docker忽略匹配模式路徑下的目錄和文件。例如:
# comment*/tmp**/*/tmp*tmp?~*5、Dockerfile編寫小結(jié)
從需求出發(fā),定制適合自己需求、高效方便的鏡像,可以參考他人優(yōu)秀的Dockerfile文件,在構(gòu)建中慢慢優(yōu)化Dockerfile文件:
1.精簡鏡像用途: 盡量讓每個(gè)鏡像的用途都比較集中、單一,避免構(gòu)造大而復(fù)雜、多功能的鏡像; 2.選用合適的基礎(chǔ)鏡像: 過大的基礎(chǔ)鏡像會(huì)造成構(gòu)建出臃腫的鏡像,一般推薦比較小巧的鏡像作為基礎(chǔ)鏡像; 3.提供詳細(xì)的注釋和維護(hù)者信息: Dockerfile也是一種代碼,需要考慮方便后續(xù)擴(kuò)展和他人使用; 4.正確使用版本號(hào): 使用明確的具體數(shù)字信息的版本號(hào)信息,而非latest,可以避免無法確認(rèn)具體版本號(hào),統(tǒng)一環(huán)境; 5.減少鏡像層數(shù): 減少鏡像層數(shù)建議盡量合并RUN指令,可以將多條RUN指令的內(nèi)容通過&&連接; 6.及時(shí)刪除臨時(shí)和緩存文件: 這樣可以避免構(gòu)造的鏡像過于臃腫,并且這些緩存文件并沒有實(shí)際用途; 7.提高生產(chǎn)速度: 合理使用緩存、減少目錄下的使用文件,使用.dockeringore文件等; 8.調(diào)整合理的指令順序: 在開啟緩存的情況下,內(nèi)容不變的指令盡量放在前面,這樣可以提高指令的復(fù)用性; 9.減少外部源的干擾: 如果確實(shí)要從外部引入數(shù)據(jù),需要制定持久的地址,并帶有版本信息,讓他人可以重復(fù)使用而不出錯(cuò)。?
分類:?Docker?
轉(zhuǎn)載于:https://www.cnblogs.com/freeliver54/p/10163258.html
總結(jié)
以上是生活随笔為你收集整理的[转]Docker基础-使用Dockerfile创建镜像的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2018.12.22 spoj7258
- 下一篇: 我的BLOG:阅读目录