Dockerfile常見命令

Dockerfile結構

Dockerfile的結構分紅了若干部分,每一個部分之間的前後順序有明確的要求:java

部分 命令
基礎鏡像信息 FROM
維護者信息 MAINTAINER
鏡像操做指令 RUNCOPYADDEXPOSEWORKDIRONBUILDUSERVOLUME
啓動時命令 CMD, ENTRYPOINT

Dockerfile示例

攜程Apollo開源項目的Dockerfile爲例:nginx

# Dockerfile for apollo-adminservice
# 1. Copy apollo-adminservice-${VERSION}-github.zip to current directory
# 2. Build with: docker build -t apollo-adminservice .
# 3. Run with: docker run -p 8090:8090 -d -v /tmp/logs:/opt/logs --name apollo-adminservice apollo-adminservice

FROM openjdk:8-jre-alpine
MAINTAINER ameizi <sxyx2008@163.com>

ENV VERSION 1.5.0-SNAPSHOT
ENV SERVER_PORT 8090
# DataSource Info
ENV DS_URL ""
ENV DS_USERNAME ""
ENV DS_PASSWORD ""

RUN echo "http://mirrors.aliyun.com/alpine/v3.8/main" > /etc/apk/repositories \
    && echo "http://mirrors.aliyun.com/alpine/v3.8/community" >> /etc/apk/repositories \
    && apk update upgrade \
    && apk add --no-cache procps unzip curl bash tzdata \
    && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone

ADD apollo-adminservice-${VERSION}-github.zip /apollo-adminservice/apollo-adminservice-${VERSION}-github.zip

RUN unzip /apollo-adminservice/apollo-adminservice-${VERSION}-github.zip -d /apollo-adminservice \
    && rm -rf /apollo-adminservice/apollo-adminservice-${VERSION}-github.zip \
    && sed -i '$d' /apollo-adminservice/scripts/startup.sh \
    && chmod +x /apollo-adminservice/scripts/startup.sh \
    && echo "tail -f /dev/null" >> /apollo-adminservice/scripts/startup.sh

EXPOSE $SERVER_PORT

CMD ["/apollo-adminservice/scripts/startup.sh"]

註釋

Dockerfile中使用#進行行註釋。git

ADD 複製文件

格式:github

ADD <src> <dest>

src複製文件到容器中的destweb

注意:docker

  1. src能夠是文件、目錄、URL或壓縮包,可是必須在構建上下文也就是Dockerfile所在的目錄中
  2. dest/結尾,則認爲src是一個目錄;dest不以/結尾,則認爲src是一個文件。
  3. 若是src是可識別的壓縮包格式(gzip, bzip2, xz),則Docker會自動解壓到容器的指定destdest中重名的文件不會被覆蓋。
  4. 若是指定的dest不存在,則會自動建立dest(含路徑中的任何目錄),新建立的文件和目錄的模式爲755,UIG和GID都是0。

ARG 設置構建參數

ARG設置構建時的環境變量,這些指定的參數在容器運行時再也不有用。ubuntu

示例數組

ARG build # 聲明一個構建參數,但沒有賦缺省值

ARG webapp_user=wasuser # 聲明一個構建參數並指定缺省值

docker build命令構建鏡像時,經過--build-arg指定構建參數的值,例如:bash

docker build --build-arg build=12345 -t darren/test_image .

此時構建Dockerfile中使用到的build的實際值是12345,而webapp_user的實際值是其缺省值。app

CMD 容器啓動命令

CMD指定容器啓動時執行的一條命令。

不一樣於RUN命令,RUN指令指定鏡像被構建時要執行的命令,CMD指定容器啓動時要執行的命令。

每一個Dockerfile只有一個CMD命令,若是指定了多條CMD命令,則只有最後一條會被執行。

啓動容器時若是經過命令行指定了運行的命令,將會覆蓋Dockerfile中指定的CMD命令。

Docker推薦使用數組語法設置要執行的命令:

CMD ["/bin/bash", "-l"]

COPY 複製文件

COPY相似於ADD

格式:

COPY <src> <dest>

注意:

  1. COPY不支持URL和壓縮包。
  2. 若是src是一個目錄,則將其中的全部文件拷貝到dest,而不含src自己;
  3. dest必須是一個絕對路徑
  4. 該指令建立的文件或目錄的UID和GID都是0
  5. 複製時保留被拷貝目錄/文件的元數據

ENTRYPOINT 入口點

CMD指令相似,一樣指定容器啓動時執行的命令。

docker run命令中指定的任何參數都會被當作參數再次傳遞給ENTRYPOINT指定的命令。

格式:

ENTRYPOINT ["executable", "param1", "param2"]

ENTRYPOINT command arg1 arg2

示例:

在Dockerfile中:

ENTRYPOIINT ["/usr/sbin/nginx"]

docker run命令中:

docker run -t -i darren/test_image -g "daemon off;"

其中的參數-g "daemon off;"會傳遞給ENTRYPOINT指定的命令,接在ENTRYPOINT以後,所以,最終實際在啓動容器時執行的至關於ENTRYPOINT指令:

ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

其含義是前臺進程的形式運行Nginx守護進程。

ENTRYPOINTCMD同時使用時,全部命令行中指定的參數會傳遞給ENTRYPOINT指令,覆蓋CMD指定的參數;當命令行沒有額外指定參數時,則ENTRYPOINTCMD指定的參數做爲默認的輸入。

示例:

ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-h"]

此時能夠在docker run命令中顯示指定參數從而修改ENTRYPOINT指令的參數,或者使用CMD傳給ENTRYPOINT指令的參數,至關於/usr/sbin/nginx -h,即顯示Nginx的幫助。

ENV 設置環境變量

ENV設置環境變量,設置的環境變量在容器運行時能夠在容器內獲取和使用,後續的RUN指令等可使用ENV指令設置的環境變量。

示例:

  1. 一次定義多個環境變量
ENV RVM_PATH=/home/rvm RVM_ARCHFLAGS="-arch amd64"
  1. 使用環境變量
ENV JAVA_HOME /path/to/java
WORKDIR $JAVA_HOME

ENV指令指定的環境變量會保存到構建的全部容器中,例如Linux容器中經過env命令來查看容器運行時的環境變量。

docker run命令中經過-e選項傳遞的環境變量只對該命令啓動的容器當次運行生效。

EXPOSE 聲明暴露的端口

聲明容器對外暴露的端口號:

EXPOSE <port1>

EXPOSE <port1> <port2> <port3>

運行時容器真實暴露的端口以命令行中的設定爲準,若是在啓動一個容器時但願使用其Dockerfile中聲明的端口,則使用-P選項:

docker run -P your-docker-image

FROM 指定基礎鏡像

FROM指定構建使用的基礎鏡像,FROM命令必須寫在其餘的指令前。

格式:

FROM <image>

FROM <image>:<tag>

FROM <image>@<digest>

LABEL 添加鏡像元數據

LABEL指令添加的元數據須要以鍵值對的形式指定。

示例:

LABEL version="1.0.0"

LABEL description="This description illustrates \
that label-values can span multi lines."

LABEL key1="v1" k2="v2" k3="v3"

注意:

  1. LABEL指令的值中,\能夠用來換行。
  2. 推薦將全部元數據放到一條LABEL中執行
  3. 能夠經過docker inspect命令來查看鏡像的標籤

MAINTAINER 維護者信息

用於爲Dockerfile署名。

示例:

MAINTAINER darren<darren@darren_s.com>

RUN 執行命令

RUN不一樣於CMD指令,RUN能夠在Dockerfile中出現和執行屢次。

在Shell終端中執行命令,Linux中默認是/bin/sh -c,Windows中是cmd /s /c

格式:

RUN <command>

RUN ["executable", "arg1", "arg2", ..., "argN"]

示例:

RUN ["/bin/sh", "-c", "echo Hello Wolrd!"]

USER 指定啓動用戶

指定啓動時的用戶,後續的指令都將以該用戶執行命令。

示例:

USER wasuser

使用USER指令的各類方式

USER user

USER user:group

USER uid

USER uid:gid

USER user:gid

USER uid:group

如不經過USER指令指定用戶,默認的用戶爲root

能夠在docker run命令中經過-u選項覆蓋該指令的值。

VOLUME 指定掛載點

向容器添加捲,一個卷是能夠存在於一個或多個容器內的特定目錄。

使容器內的一個目錄具備持久化存儲的功能,被指定的目錄既能夠被容器自己使用,也能夠共享給其餘容器。

  • 卷能夠在容器之間共享和重用
  • 一個容器能夠不和別的容器共享卷
  • 對卷的修改當即生效
  • 對卷的修改不會對更新鏡像產生影響
  • 卷一直存在到沒有容器再使用它

示例:

VOLUME /mnt/data

該指令爲每一個基於該鏡像建立的容器建立一個名爲/mnt/data的掛載點。也能夠指定多個卷:

VOLUME ["/mnt/project1", "/mnt/project2"]

WORKDIR 指定工做目錄

從鏡像建立容器時,在容器內設置一個工做目錄。

至關於Linux中的cd命令,用於切換到指定的工做目錄,後續的指令都將在指定的工做目錄下執行。

WORKDIR指令能夠屢次出現,在不一樣的工做目錄之間進行切換:

WORKDIR /opt/webapp/db
RUN bundle install
WORKDIR /opt/webapp
RUN [ "rackup" ]

啓動容器時可使用-w選項覆蓋工做目錄:

docker run -it -w /var/log ubuntu pwd

會將容器內的工做目錄設置爲/var/log

ONBUILD指令

爲鏡像添加觸發器,當鏡像A被做爲鏡像B的基礎鏡像,在構建鏡像B時,會執行鏡像A的ONBUILD指令。

注意:

  1. ONBUILD指令按照其在鏡像A中聲明的順序依次執行
  2. ONBUILD指令只能被繼承一次,即若是鏡像C再以鏡像B做爲基礎鏡像,構建鏡像C時不會觸發鏡像A的ONBUILD指令。
  3. 能夠認爲鏡像A的ONBUILD指令在鏡像B的FROM指令後當即執行。
  4. FROMMAINTAINERONBUILD指令是不能出如今ONBUILD指令中的。

示例

鏡像A中:

ONBUILD ADD . /var/www

鏡像B

FROM 鏡像A

則會在構建鏡像B的Step 0 : FROM階段就執行鏡像A的ONBUILD指令,即將構建上下文中的全部內容添加到/var/www目錄

相關文章
相關標籤/搜索