九、Dockerfile語法

  在Dockerfile中定義了不少關鍵字,經過關鍵字來完成Dockerfile的編寫。
  Dockerfile官方文檔python

9.1 FROM

  在Dockerfile中FROM主要是指定這個Dockerfile基於哪個base image構建。Docker Dockerfile按順序運行指令。一個Dockerfile 必須用FROM指令啓動,放在第一行。mysql

FROM scratch        # 製做base image
FROM centos         # 使用base image
FROM ubuntu:14.04   # 使用指定版本的base image

安全起見,儘可能使用官方的image做爲base image。sql

9.2 LABEL

  在Dockerfile中LABEL其實是英譯了Metadata,就像是代碼中的註釋。主要包含了該鏡像的做者、版本和描述信息。docker

LABEL maintainer="staryjie@163.com"
LABEL version="1.0"
LABEL description="This is description"

Metadata不可少!shell

9.3 RUN

  在Dockerfile中RUN用來運行命令,其中命令必須是在第一行FROM中指定的base image所能運行的。每運行一次RUN,構建的image都會生成新的一層layer。ubuntu

RUN yum update && yum install -y vim \
    python-dev                # 反斜槓換行
RUN apt-get update && apt-get install -y perl \
    pwgen --no-install-recommends && rm -rf \
    /var/lib/apt/lists/*      # 注意清理cache
RUN /bin/bash -C 'source $HOME/.bashrc;echo $HOME'

爲了美觀,複雜的RUN可使用反斜槓換行。
爲了不無用分層,多條命令儘可能合併一行。vim

9.4 WORKDIR

  在Dockerfile中WORKDIR用來設定當前工做目錄,相似Linux系統中的cd命令。centos

WORKDIR /root
WORKDIR /test        # 若是沒有該目錄,則會自動建立
WORKDIR demo
RUN pwd              # 輸出的結果應該是/test/demo

用WORKDIR,不要使用RUN cd !!!
爲了不出錯,儘可能使用絕對路徑。安全

9.4 ADD和COPY

  在Dockerfile中ADD和COPY做用類似,都是把本地的文件添加到docker image中。區別:ADD不只能夠添加文件,還能夠解壓縮文件,COPY不能夠解壓縮文件。bash

ADD hello /
ADD test.tar.gz /        # 添加到image的根目錄而且解壓
WORKDIR /root
ADD hello test/          # 將hello添加到image的/root/test/hello
WORKDIR /root
COPY hello test/         # 跟上面的效果同樣

大部分狀況下COPY優於ADD。
ADD除了COPY還有額外功能(解壓)。
添加遠程文件/目錄,請使用curl或者wget。

9.5 ENV

  在Dockerfile中ENV來設置環境變量或者一些常量。能夠在ENV設置的常量後面直接使用。

ENV MYSQL_VERSION 5.6        # 設置常量
RUN apt-get install -y mysql-server="${MYSQL_VERSION}" \
    && rm -rf /var/lib/apt/lists/*        #引用常量

儘可能使用ENV增長可維護性!

9.6 VOLUME

  在Dockerfile中VOLUME用於向基於鏡像建立的容器添加捲,一個卷能夠存在於一個或多個容器的特定目錄,這個目錄能夠繞過聯合文件系統,並提供共享數據、數據持久化的功能。

VOLUME ["/data"]

9.7 EXPOSE

  在Dockerfile中EXPOSE設置容器暴露的端口,能夠指定一個或多個端口。

EXPOSE 80

雖然在EXPOSE指令中已經暴露了指定的端口,可是在啓動容器的時候仍是要指定端口信息,容器自己不會自動暴露端口。

9.8 CMD

  在Dockerfile中CMD設置容器啓動後默認執行的命令和參數。若是定義了多個CMD,只會執行最後一個。

CMD ["executable","param1","param2"]        # 執行形式,這是首選形式
CMD ["param1","param2"]                     # 做爲進入點的默認參數
CMD command param1 param2                   # 殼形式

不要定義多個CMD,多個CMD只有最後一個會執行。

9.9 ENTRYPOINT

  在Dockerfile中ENTRYPOINT設置容器啓動時運行的命令,可讓容器以應用程序或者服務器的形式運行,並且ENTRYPOINT設定的命令不會被忽略,必定會執行。

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

能夠寫一個shell腳本做爲ENTRYPOINT的入口。

RUN、CMD、ENTRYPOINT對比

  • RUN 執行命令並建立新的image layer
  • CMD 設置容器啓動後默認執行的命令和參數
  • ENTRYPOINT 設置容器啓動時運行的命令

shell格式和exec格式

  • shell格式
RUN apt-get install -y vim
CMD echo "hello docker"
ENTRYPOINT echo "hello docker"

  Dockerfile

FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"

  構建鏡像:

docker build -t staryjie/centos-entrypoint-shell .

  運行容器:

docker run staryjie/centos-entrypoint-shell

hello Docker
  • exec格式
RUN ["apt-get","install","-y","vim"]
CMD ["/bin/echo","hello docker"]
ENTRYPOINT ["/bin/echo","hello docker"]

  Dockerfile

FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo","hello $name"]

  構建鏡像:

docker build -t staryjie/centos-entrypoint-exec .

  運行容器:

docker run staryjie/centos-entrypoint-exec

hello $name

  改寫Dockerfile

FROM centos
ENV name Docker
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]

  構建鏡像:

docker build -t staryjie/centos-entrypoint-exec-new .

  運行容器:

docker run staryjie/centos-entrypoint-exec-new

hello Docker
  1. CMD
    • 容器啓動時默認執行的命令
    • 若是docker run指定了其餘命令,CMD命令會被忽略
    • 若是定義了多個CMD,只有最後一個會執行
  2. ENTRYPOINT
    • 讓容器以應用程序或者服務的形式運行
    • 不會被忽略,必定會執行
相關文章
相關標籤/搜索