Dockerfile 是一個文本格式的配置文件,用戶可以使用 Dockerfile 快速創(chuàng)建自定義的鏡像。我們會先介紹 Dockerfile 的基本結(jié)構(gòu)及其支持的眾多指令,并具體講解通過執(zhí)行指令來編寫定制鏡像的 Dockerfile。
基本結(jié)構(gòu)
Dockerfile 由一行行命令語句組成,并且支持已 # 開頭的注釋行。一般而言,Dockerfile 的內(nèi)容分為四個部分:基礎(chǔ)鏡像信息、維護(hù)者信息、鏡像操作指令和容器啟動時執(zhí)行指令。例如:
# This dockerfile uses the Ubuntu image
# VERSION 2
# Author: docker_user
# Command format: Instruction [arguments / command] …
# 第一行必須指定基于的容器鏡像
FROM ubuntu
# 維護(hù)者信息
MAINTAINER docker_user docker_user@email.com
# 鏡像的操作指令
RUN echo “deb raring main universe” >> /etc/apt/sources.list
RUN apt-get update && apt-get install -y nginx
RUN echo “\ndaemon off;” >> /etc/nginx/nginx.conf
# 容器啟動時執(zhí)行指令
CMD /usr/sbin/nginx
其中,一開始必須指明所基于的鏡像名稱,接下來一般會說明維護(hù)者的信息。后面則是鏡像操作指令,例如 RUN 指令,RUN 指令將對鏡像執(zhí)行跟隨的命令。每運(yùn)行一條 RUN 指令,鏡像添加新的一層,并提交。最后是 CMD 指令,來指定運(yùn)行容器時的操作命令。
下面是兩個 dockerhub 上的例子,同學(xué)們可以對 Dockerfile 結(jié)構(gòu)有個基本的感知。
第一個是在 Ubuntu 鏡像的基礎(chǔ)上安裝 inotify-tools、nginx、apache2、openssh-server 等軟件,從而創(chuàng)建一個新的 nginx 鏡像:
# nginx
# VERSION 0.0.1
FROM ubuntu
MAINTAINER Victor Vieus
RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
第二個也是基于 ubuntu 鏡像,安裝 firefox 和 vnc 軟件,啟動后,用戶可以通過 5900 端口通過 vnc 方式使用 firefox:
# Firefox over VNC
# VERSION 0.3
FROM Ubuntu
# Install vnc, xvfb in order to create a ‘fake' display and firefox
RUN apt-get update && apt-get install -y x11vnc xvfb firefox
RUN mkdir /.vnc
# setup a password
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox
RUN bash -c ‘echo “firefox” >> /.bashrc'
EXPOSE 5900
CMD [“x11vnc”, “-forever”, “-usepw”, “-create”]
指令
指令的一般格式為 INSTRUCTION arguments,指令包括 FROM、MAINTAINER、RUN 等,下面分別介紹。
FROM
格式為 FROM
Dockerfile 的第一條指令必須為 FROM 指令。并且,如果在同一個 Dockerfile 中創(chuàng)建多個鏡像時,可以使用多個 FROM 指令。
MAINTAINER
格式為 MAINTAINER ,指定維護(hù)者信息。
注意:MAINTAINER 指令已經(jīng)被拋棄,建議使用 LABEL 指令。
LABEL
格式為:
LABEL = = = ...
LABEL 指令為鏡像添加標(biāo)簽。一個 LABEL 就是一個鍵值對。
下面是一些例子:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \that label-values can span multiple lines."
我們可以給鏡像添加多個 LABEL,需要注意的是,每條 LABEL 指令都會生成一個新的層。所以最好是把添加的多個 LABEL 合并為一條命令:
LABEL multi.label1="value1" multi.label2="value2" other="value3"
也可以寫成這樣:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
如果新添加的 LABEL 和已有的 LABEL 同名,則新值會覆蓋掉舊值。
我們可以使用 docker inspect 命令查看鏡像的 LABEL 信息。
RUN
有兩種格式,分別為:
RUN
RUN [“executable”, “param1”, “param2”]
前者將在 shell 終端中運(yùn)行命令,即 /bin/sh -c,后者則使用 exec 執(zhí)行。指定使用其他終端可以通過第二種方式實(shí)現(xiàn),例如 RUN [“/bin/bash”, “-c”, “echo hello”]。
每條 RUN 指令將在當(dāng)前鏡像的基礎(chǔ)上執(zhí)行指定命令,并提交為新的鏡像。當(dāng)命令較長時可以使用 \ 來換行。
CMD
支持三種格式:
CMD [“executable”, “param1”, “param2”] 使用 exec 執(zhí)行,推薦方式。
CMD command param1 param2 在 /bin/sh 中執(zhí)行,提供給需要交互的應(yīng)用。
CMD [“param1”, “param2”] 提供給 ENTRYPOINT 的默認(rèn)參數(shù)。