Dockerfile#
使用 Dockerfile 讓使用者可以建立自定義的映像檔。
基本結構#
Dockerfile 由一行行命令語句組成,並且支援以 # 開頭的註解行。一般而言,Dockerfile 分為四部分:基底映像檔資訊、維護者資訊、映像檔操作指令和容器啟動時執行指令。一個 Dockerfile 範例如下:
# This dockerfile uses the ubuntu image
# VERSION 2 - EDITION 1
# Author: docker_user
# Command format: Instruction [arguments / command] ..
# 基本映像檔,必須是第一個指令
FROM ubuntu# 維護者: docker_user (@docker_user)
MAINTAINER docker_user docker_user@email.com# 更新映像檔的指令
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# 建立新容器時要執行的指令
CMD /usr/sbin/nginx
其中,一開始必須指明作為基底的映像檔名稱,接下來說明維護者資訊(建議)。接著則是映像檔操作指令,例如 RUN 指令, RUN 指令將對映像檔執行相對應的命令。每運行一條 RUN 指令,映像檔就會新增一層。最後是 CMD 指令,指定執行容器時的操作命令。
下面來看一個更複雜的例子:
# Nginx
#
# VERSION 0.0.1
FROM ubuntu
MAINTAINER Victor Vieux <victor@docker.com>
RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server# 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 (might not be the best way, but it does the trick)
RUN bash -c 'echo "firefox" >> /.bashrc'
EXPOSE 5900
CMD ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example
#
# VERSION 0.1
FROM ubuntu
RUN echo foo > bar# Will output something like ===> 907ad6c2736f
FROM ubuntu
RUN echo moo > oink# Will output something like ===> 695d7793cbe4
# You᾿ll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
# /oink.
# This dockerfile uses the ubuntu image # VERSION 2 - EDITION 1 # Author: docker_user # Command format: Instruction [arguments / command] .. # 基本映像檔,必須是第一個指令 FROM ubuntu# 維護者: docker_user(@docker_user) MAINTAINER docker_user docker_user@email.com# 更新映像檔的指令 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# 建立新容器時要執行的指令 CMD /usr/sbin/nginx
# Nginx # # VERSION 0.0.1 FROM ubuntu MAINTAINER Victor Vieux <victor@docker.com> RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server# 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 (might not be the best way, but it does the trick) RUN bash -c 'echo "firefox" >> /.bashrc' EXPOSE 5900 CMD ["x11vnc", "-forever", "-usepw", "-create"] # Multiple images example # # VERSION 0.1 FROM ubuntu RUN echo foo > bar# Will output something like ===> 907ad6c2736f FROM ubuntu RUN echo moo > oink# Will output something like ===> 695d7793cbe4 # You᾿ll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with # /oink.
指令#
指令的一般格式為 INSTRUCTION arguments ,指令包括 FROM 、 MAINTAINER 、 RUN 等。
FROM#
格式為 FROM <image>, FROM <image>:<tag> 或 FROM <image>@<digest>
第一條指令必須為 FROM 指令。並且,如果在同一個 Dockerfile 中建立多個映像檔時,可以使用多個 FROM 指令(每個映像檔一次)。
MAINTAINER#
格式為 MAINTAINER <name> ,指定維護者訊息。
RUN#
格式為 RUN <command> 或 RUN ["executable", "param1", "param2"] 。
前者將在 shell 終端中運行命令,即 /bin/sh -c ;後者則使用 exec 執行。指定使用其它終端可以透過第二種方式實作,例如 RUN ["/bin/bash", "-c", "echo hello"] 。 每條 RUN 指令將在當前映像檔基底上執行指定命令,並產生新的映像檔。當命令較長時可以使用 \ 來換行。
CMD#
CMD 支援三種格式:
- CMD ["executable","param1","param2"] 使用 exec 執行,推薦使用;
- CMD command param1 param2 在 /bin/sh 中執行,使用在給需要互動的指令;
- CMD ["param1","param2"] 提供給 ENTRYPOINT 的預設參數;
指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 CMD 命令。如果指定了多條命令,只有最後一條會被執行。如果使用者啟動容器時候指定了運行的命令,則會覆蓋掉 CMD 指定的命令。
EXPOSE#
格式為 EXPOSE <port> [<port>...] 。
設定 Docker 伺服器容器對外的埠號,供外界使用。在啟動容器時需要透過 -P,Docker 會自動分配一個埠號轉發到指定的埠號。
ENV#
格式為 ENV <key> <value> 或 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
... 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> 或 ADD ["<src>"... "<dest>"] (this form is required for paths containing whitespace)
該命令將複製指定的 <src> 到容器中的 <dest> 。 其中 <src> 可以是 Dockerfile 所在目錄的相對路徑;也可以是一個 URL;還可以是一個 tar 檔案(其複製後會自動解壓縮)。並且 <src> 中可以包含 "*" 或 "?" (using Go's filepath.Match rules), 一個使用範例如下:
ADD hom* /mydir/ # adds all files starting with "hom"
ADD hom?.txt /mydir/ # ? is replaced with any single character
ADD hom* /mydir/ # adds all files starting with "hom" ADD hom?.txt /mydir/ # ? is replaced with any single character
COPY#
COPY 支援以下兩個格式:
- COPY <src>... <dest>
- COPY ["<src>"... "<dest>"] (this form is required for paths containing whitespace)
複製本地端的 <src> (為 Dockerfile 所在目錄的相對路徑)到容器中的 <dest> 。
ENTRYPOINT#
ENTRYPOINT 支援以下兩種格式:
- ENTRYPOINT ["executable", "param1", "param2"] (the preferred exec form)
- ENTRYPOINT command param1 param2 (shell form)
指定容器啟動後執行的命令,並且不會被 docker run 提供的參數覆蓋。每個 Dockerfile 中只能有一個 ENTRYPOINT ,當指定多個時,只有最後一個會生效。
VOLUME#
格式為 VOLUME ["/data"] 。
建立一個可以從本地端或其他容器掛載的掛載點,一般用來存放資料庫和需要保存的資料等。
USER#
格式為 USER daemon 。
指定運行容器時的使用者名稱或 UID,後續的 RUN 也會使用指定使用者。
當服務不需要管理員權限時,可以透過該命令指定運行使用者。並且可以在之前建立所需要的使用者,例如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要臨時取得管理員權限可以使用 gosu ,而不推薦 sudo
WORKDIR#
格式為 WORKDIR /path/to/workdir 。
為後續的 RUN 、 CMD 、 ENTRYPOINT 指令指定工作目錄。
可以使用多個 WORKDIR 指令,後續命令如果參數是相對路徑,則會基於之前命令指定的路徑。例如:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
則最終路徑為 /a/b/c。
WORKDIR /a WORKDIR b WORKDIR c RUN pwd
ONBUILD#
格式為 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 。
[...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src[...]
FROM image-A#Automatically run the following ADD . /app/src RUN /usr/local/bin/python-build --dir /app/src
建立映像檔#
(P90) 編輯完成 Dockerfile 之後,可以透過 docker build 命令建立映像檔。
基本的格式為 docekr build [選項] 路徑 ,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,並將該路徑下所有內容發送給 Docker 伺服端,由伺服端來建立映像檔。因此一般會建議放置 Dockerfile 的目錄為空目錄。也可以透過 .dockerignore 檔案(每一行新增一條排除模式:exclusion patterns)來讓 Docker 忽略路徑下的目錄和檔案。
要指定映像檔的標籤資訊,可以透過 -t 選項,例如:
# docker build -t myrepo/myapp /tmp/test1%
從映像檔產生 Dockerfile#
CenturyLinkLabs 釋出 dockerfile-from-image 工具,以逆向工程建立出 Dockerfile 。 類似 docker history 指令,透過映像檔每一層的 metadata 來重建出那 Dockerfile ,即便沒有提供任何資訊。
使用方法#
首先 docker pull centurylink/dockerfile-from-image 這已包好 Ruby script 的映像檔, 接下來,執行下面命令,就可得到反推所產生的 Dockerfile.txt:
# docker run -v /var/run/docker.sock:/var/run/docker.sock \
centurylink/dockerfile-from-image <IMAGE_TAG_OR_ID> > Dockerfile.txt
那 <MAGE_TAG_OR_ID> 參數可以任何包含 tag 的映像檔名稱。
centurylink/dockerfile-from-image <IMAGE_TAG_OR_ID> > Dockerfile.txt
範例#
以下是個試範,如何將官方 Ruby 的映像檔來產生出 Dockerfile。
# docker pull ruby
# docker run -v /run/docker.sock:/run/docker.sock centurylink/dockerfile-from-image
Usage: dockerfile-from-image.rb [options] <image_id>
-f, --full-tree Generate Dockerfile for all parent layers
-h, --help Show this message
# docker run -v /run/docker.sock:/run/docker.sock centurylink/dockerfile-from-image ruby
FROM buildpack-deps:latest
RUN useradd -g users user
RUN apt-get update && apt-get install -y bison procps
RUN apt-get update && apt-get install -y ruby
...
# docker run -v /run/docker.sock:/run/docker.sock centurylink/dockerfile-from-image
Usage: dockerfile-from-image.rb [options] <image_id>
-f, --full-tree Generate Dockerfile for all parent layers
-h, --help Show this message
# docker run -v /run/docker.sock:/run/docker.sock centurylink/dockerfile-from-image ruby
FROM buildpack-deps:latest
RUN useradd -g users user
RUN apt-get update && apt-get install -y bison procps
RUN apt-get update && apt-get install -y ruby
...
沒有留言:
張貼留言