Dockfile是一種被Docker程序解釋的腳本,Dockerfile由一條一條的指令組成纳猪,每條指令對應(yīng)Linux下面的一條命令。Docker程序?qū)⑦@些Dockerfile指令翻譯真正的Linux命令。Dockerfile有自己書寫格式和支持的命令倔毙,Docker程序解決這些命令間的依賴關(guān)系,類似于Makefile乙濒。Docker程序?qū)⒆x取Dockerfile陕赃,根據(jù)指令生成定制的image。相比image這種黑盒子颁股,Dockerfile這種顯而易見的腳本更容易被使用者接受么库,它明確的表明image是怎么產(chǎn)生的。有了Dockerfile甘有,當(dāng)我們需要定制自己額外的需求時诉儒,只需在Dockerfile上添加或者修改指令,重新生成image即可亏掀,省去了敲命令的麻煩忱反。
在 Dockerfile 中用到的命令有
FROM
FROM指定一個基礎(chǔ)鏡像, 一般情況下一個可用的 Dockerfile一定是 FROM 為第一個指令滤愕。至于image則可以是任何合理存在的image鏡像温算。
FROM 一定是首個非注釋指令 Dockerfile.
FROM 可以在一個 Dockerfile 中出現(xiàn)多次,以便于創(chuàng)建混合的images该互。
如果沒有指定 tag 米者,latest 將會被指定為要使用的基礎(chǔ)鏡像版本。
MAINTAINER
這里是用于指定鏡像制作者的信息
RUN
RUN命令將在當(dāng)前image中執(zhí)行任意合法命令并提交執(zhí)行結(jié)果宇智。命令執(zhí)行提交后蔓搞,就會自動執(zhí)行Dockerfile中的下一個指令。
層級 RUN 指令和生成提交是符合Docker核心理念的做法随橘。它允許像版本控制那樣喂分,在任意一個點(diǎn),對image 鏡像進(jìn)行定制化構(gòu)建机蔗。
RUN 指令緩存不會在下個命令執(zhí)行時自動失效蒲祈。比如 RUN apt-get dist-upgrade -y 的緩存就可能被用于下一個指令. --no-cache 標(biāo)志可以被用于強(qiáng)制取消緩存使用甘萧。
ENV
ENV指令可以用于為docker容器設(shè)置環(huán)境變量
ENV設(shè)置的環(huán)境變量,可以使用 docker inspect命令來查看梆掸。同時還可以使用docker run --env <key>=<value>來修改環(huán)境變量扬卷。
USER
USER 用來切換運(yùn)行屬主身份的。Docker 默認(rèn)是使用 root酸钦,但若不需要炒辉,建議切換使用者身分度液,畢竟 root 權(quán)限太大了玛臂,使用上有安全的風(fēng)險尔店。
WORKDIR
WORKDIR 用來切換工作目錄的。Docker 默認(rèn)的工作目錄是/欢伏,只有 RUN 能執(zhí)行 cd 命令切換目錄入挣,而且還只作用在當(dāng)下下的 RUN,也就是說每一個 RUN 都是獨(dú)立進(jìn)行的硝拧。如果想讓其他指令在指定的目錄下執(zhí)行径筏,就得靠 WORKDIR。WORKDIR 動作的目錄改變是持久的河爹,不用每個指令前都使用一次 WORKDIR匠璧。
COPY
COPY 將文件從路徑 <src> 復(fù)制添加到容器內(nèi)部路徑 <dest>。
<src>
必須是想對于源文件夾的一個文件或目錄咸这,也可以是一個遠(yuǎn)程的url夷恍,<dest>
是目標(biāo)容器中的絕對路徑。
所有的新文件和文件夾都會創(chuàng)建UID 和 GID 媳维。事實上如果 <src> 是一個遠(yuǎn)程文件URL酿雪,那么目標(biāo)文件的權(quán)限將會是600。
ADD
ADD 將文件從路徑 <src> 復(fù)制添加到容器內(nèi)部路徑 <dest>侄刽。
<src> 必須是想對于源文件夾的一個文件或目錄指黎,也可以是一個遠(yuǎn)程的url。<dest> 是目標(biāo)容器中的絕對路徑州丹。
所有的新文件和文件夾都會創(chuàng)建UID 和 GID醋安。事實上如果 <src> 是一個遠(yuǎn)程文件URL,那么目標(biāo)文件的權(quán)限將會是600墓毒。
VOLUME
創(chuàng)建一個可以從本地主機(jī)或其他容器掛載的掛載點(diǎn)吓揪,一般用來存放數(shù)據(jù)庫和需要保持的數(shù)據(jù)等。
EXPOSE
EXPOSE 指令指定在docker允許時指定的端口進(jìn)行轉(zhuǎn)發(fā)所计。
CMD
Dockerfile.中只能有一個CMD指令柠辞。 如果你指定了多個,那么最后個CMD指令是生效的主胧。
CMD指令的主要作用是提供默認(rèn)的執(zhí)行容器叭首。這些默認(rèn)值可以包括可執(zhí)行文件习勤,也可以省略可執(zhí)行文件。
當(dāng)你使用shell或exec格式時焙格, CMD
會自動執(zhí)行這個命令图毕。
ONBUILD
ONBUILD 的作用就是讓指令延遲執(zhí)行,延遲到下一個使用 FROM 的 Dockerfile 在建立 image 時執(zhí)行眷唉,只限延遲一次吴旋。
ONBUILD 的使用情景是在建立鏡像時取得最新的源碼 (搭配 RUN) 與限定系統(tǒng)框架。
ARG
ARG是Docker1.9 版本才新加入的指令厢破。
ARG 定義的變量只在建立 image 時有效,建立完成后變量就失效消失
LABEL
定義一個 image 標(biāo)簽 Owner治拿,并賦值摩泪,其值為變量 Name 的值。(LABEL Owner=$Name )
ENTRYPOINT
是指定 Docker image 運(yùn)行成 instance (也就是 Docker container) 時劫谅,要執(zhí)行的命令或者文件见坑。
注意:
- CMD 和 ENTRYPOINT 都能用來指定開始運(yùn)行的程序,而且這兩個命令都有兩種不用的語法:
CMD ls -l
or
CMD ["ls",''-l"]
對于第一種語法捏检,docker 會自動加入“/bin/sh –c”到命令中荞驴,這樣就有可能導(dǎo)致意想不到的行為。為了避免這種行為贯城,我們推薦所有的 CMD 和 ENTRYPOINT 都應(yīng)該使用第二種語法熊楼。
如果兩個同時使用,請確定確定他們的含義沒有錯誤能犯。一般來說需要兩個同時使用的情況只有 ENTRYPOINT 指定需要運(yùn)行的 binary鲫骗,CMD 給出運(yùn)行的默認(rèn)參數(shù)。
- 盡量合并命令
Dockerfile 中的每一個命令都會創(chuàng)建一個新的 layer踩晶,而一個容器能夠擁有的最多 layer 數(shù)是有限制的执泰。所以盡量將邏輯上連貫的命令合并可以減少 layer的層數(shù),合并命令的方法可以包括將多個可以合并的命令(EXPOSE渡蜻, ENV术吝,VOLUME,COPY)合并茸苇。
Dockerfile 中的每一個命令都會創(chuàng)建一個新的 layer排苍,而一個容器能夠擁有的最多 layer 數(shù)是有限制的。所以盡量將邏輯上連貫的命令合并可以減少 layer 的層數(shù)税弃,這也可以加快編譯速度纪岁。
將多個可以合并的命令(RUN,EXPOSE, ENV,VOLUME,COPY)合并,比如:
EXOISE 80
EXOISE 8080
CMD cd /tmp
CMD ls
==>
EXOISE 80 8080
CMD cd /tmp && ls
- ADD命令和 COPY 命令在很大層度上功能是一樣的则果。但是 COPY 語義更加直接幔翰,所以我們推薦盡量使用 COPY 命令漩氨。唯一例外的是 ADD 命令自帶解壓功能,如果需要拷貝并解壓一個文件到鏡像中遗增,那么我們可以使用 ADD 命令叫惊。除此之外,我們都推薦使用 COPY 命令做修。
ADD 1.1.1.100:1234/jdk-8u74-linux-x64.tar.gz /usr/local/
- USER的使用
Docker 默認(rèn)所有的應(yīng)用都會跑在容器的 root user 底下霍狰,但是這樣會造成一些潛在的安全隱患。在 production 環(huán)境跑的 Container 最好是通過USER命令跑在非特權(quán)用戶底下饰及。