Dockerfile是一個具備規範格式的文件,根據適當的指令和語法,咱們能夠構建一個自定以鏡像。但Dockerfile須要依賴於一個原始鏡像,而這些原始鏡像咱們能夠經過官方默認鏡像倉庫方便獲取。具體獲取方法參照前文鏡像獲取辦法。node
通常的,Dockerfile 分爲四部分:基礎鏡像信息、維護者信息、鏡像操做指令和容器啓動時執行指令。好比以下一個Dockerfile文件:python
# This dockerfile uses the ubuntu image
# VERSION V1.0
# Author: 旺旺linux# 基礎鏡像,必須設置在第一個非註釋行
FROM ubuntunginx# Maintainer: 鏡像維護者信息
MAINTAINER Barlow toxingwang@qq.comdocker# 鏡像所需執行命令
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.confshell# 容器啓動命令
CMD /usr/sbin/nginx數據庫
其中,一開始必須指明所基於的鏡像名稱,接下來是說明維護者信息,固然維護者信息是可選的。ubuntu
後面則是鏡像操做指令,例如 RUN 指令,RUN 指令將對鏡像執行跟隨的命令。每運行一條 RUN 指令,鏡像添加新的一層,並提交。centos
最後是 CMD 指令,來指定運行容器時的操做命令。ruby
指令的通常格式爲 INSTRUCTION arguments,指令包括 FROM、MAINTAINER、RUN 等。
格式爲
FROM <image>
或
FROM <image>:<tag>
第一條指令必須爲 FROM 指令。而且,若是在同一個Dockerfile中建立多個鏡像時,可使用多個 FROM 指令(每一個鏡像一次)。
格式爲 MAINTAINER <name>,指定維護者信息。
格式爲
RUN <command>
或
RUN ["executable", "param1", "param2"]
前者將在 shell 終端中運行命令,即 /bin/sh -c;後者則使用 exec 執行。指定使用其它終端能夠經過第二種方式實現,例如 RUN ["/bin/bash", "-c", "echo hello"]。
每條 RUN 指令將在當前鏡像基礎上執行指定命令,並提交爲新的鏡像。當命令較長時可使用 \ 來換行。
支持三種格式
CMD ["executable","param1","param2"] #使用 exec 執行,推薦方式;
CMD command param1 param2 #在 /bin/sh 中執行,提供給須要交互的應用;
CMD ["param1","param2"] #提供給 ENTRYPOINT 的默認參數;
指定啓動容器時執行的命令,每一個 Dockerfile 只能有一條 CMD 命令。若是指定了多條命令,只有最後一條會被執行。
若是用戶啓動容器時候指定了運行的命令,則會覆蓋掉 CMD 指定的命令。
格式爲 EXPOSE <port> [<port>...]。
告訴 Docker 服務端容器暴露的端口號,供互聯繫統使用。在啓動容器時須要經過 -P,Docker 主機會自動分配一個端口轉發到指定的端口。
格式爲 ENV <key> <value> 。指定一個環境變量,會被後續 RUN 指令使用,並在容器運行時保持。
例如
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
使用ADD命令能夠將本地的文件添加到鏡像中。
格式爲
ADD <src> <dest>
該命令將複製指定的 <src> 到容器中的 <dest>。 其中 <src> 能夠是Dockerfile文件所在目錄的一個相對路徑;也能夠是一個 URL;還能夠是一個 tar 文件(自動解壓爲目錄)。
COPY命令與ADD功能基本沒有區別,但當使用本地目錄爲源目錄時,推薦使用 COPY。
格式爲
COPY <src> <dest>
複製本地主機的 <src>(爲 Dockerfile 所在目錄的相對路徑)到容器中的 <dest>。
*注意:無論是ADD仍是COPY指令,完成拷貝後都最好執行下「RUN chmod」命令將文件或目錄的權限修改成本身須要的。
兩種格式:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2 #shell中執行
配置容器啓動後執行的命令,而且不可被 docker run 提供的參數覆蓋。
每一個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最後一個起效。
VOLUME用於建立一個能夠從本地主機或其餘容器掛載的掛載點,通常用來存放數據庫和須要保持的數據等。
格式爲
VOLUME ["/data"]
指定運行容器時的用戶名或 UID,後續的 RUN 也會使用指定用戶。
格式爲
USER daemon
當服務不須要管理員權限時,能夠經過該命令指定運行用戶。而且能夠在以前建立所須要的用戶,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres。要臨時獲取管理員權限可使用 gosu,而不推薦 sudo。
WORKDIR爲後續的 RUN、CMD、ENTRYPOINT 指令配置工做目錄。
格式爲
WORKDIR /path/to/workdir
可使用多個 WORKDIR 指令,後續命令若是參數是相對路徑,則會基於以前命令指定的路徑。例如
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
則最終路徑爲 /a/b/c。
配置當所建立的鏡像做爲其它新建立鏡像的基礎鏡像時,所執行的操做指令。
格式爲
ONBUILD [INSTRUCTION]
例如,Dockerfile 使用以下的內容建立了鏡像 image-A。
[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
若是基於 image-A 建立新的鏡像時,新的Dockerfile中使用 FROM image-A指定基礎鏡像時,會自動執行 ONBUILD 指令內容,等價於在後面添加了兩條指令。
FROM image-A
#Automatically run the following
ADD . /app/src
RUN /usr/local/bin/python-build --dir /app/src
使用 ONBUILD 指令的鏡像,推薦在標籤中註明,例如 ruby:1.9-onbuild。
編寫完成 Dockerfile 以後,能夠經過 docker build 命令來建立鏡像。
基本的格式爲
docker build [選項] 路徑
該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,並將該路徑下全部內容發送給 Docker 服務端,由服務端來建立鏡像。所以通常建議放置 Dockerfile 的目錄爲空目錄。也能夠經過 .dockerignore 文件(每一行添加一條匹配模式)來讓 Docker 忽略路徑下的目錄和文件。
要指定鏡像的標籤信息,能夠經過 -t 選項,例如:
docker build -t centos:sshd /docker/sshd
命令執行後,就會按照Dockerfile文件中的定義一層層構建docker鏡像。
固然,docker build命令很是有趣,它會反覆的執行多個命令,以下圖:
咱們從上圖能夠看到,build命令根據Dockerfile文件中的FROM指令獲取到鏡像,而後重複地:
1)run(create和start)
2)修改
3)commit
在循環中的每一步都會生成一個新的層,所以許多新的層會被建立。
咱們經過前述的相關執行,能夠方便的構建一個所需的鏡像,以下是一個包含sshd服務的鏡像Dockerfile文件:
[root@node01 sshd]# cat Dockerfile
FROM centos:6.6
MAINTAINER Barlow
ADD selinux/config /etc/selinux/config
RUN yum -y install openssh openssh-server
RUN sed -i 's/\(session.*\)required\(.*pam_loginuid.so\)/\1optional\2/' /etc/pam.d/sshd
RUN /etc/init.d/sshd start
RUN echo "root:password" | chpasswd
EXPOSE 22
CMD /usr/sbin/sshd -D
當前目錄下除Dockerfile文件外還有一個目錄selinux,其下包含了須要拷貝至鏡像中的selinux配置文件。下面爲Dockerfile文件詳細內容:
[root@node01 sshd]# ll
總用量 4
-rw-r--r-- 1 root root 299 10月 30 11:30 Dockerfile
drwxr-xr-x 2 root root 19 10月 30 11:24 selinux
使用以下命令構建鏡像:
# docker build -t centos:sshd .
鏡像構建過程是按層實現的,每一個指令就是一層。完成後以下:
啓動剛纔構建的鏡像並測試:
[root@node01 sshd]# docker run -d -p 2222:22 centos:sshd
1a91a673297c0a4f268550fa2ac819304f2410b33f8f4e239726f60d5d0a5859
[root@node01 sshd]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1a91a673297c centos:sshd "/bin/sh -c '/usr/sb 4 seconds ago Up 3 seconds 0.0.0.0:2222->22/tcp admiring_curie
[root@node01 sshd]# ssh -p 2222 127.0.0.1