Docker學習筆記---Dockerfile

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

Docker可以通過從Dockerfile包含所有命令的文字檔中讀取指令,自動構建鏡像。

每個需要使用Docker的項目都應該有一個Dockerfile,這個檔案描述了我們需要的鏡像環境。

Dockerfile指令

FROM

有效Dockerfile必須從FROM開始,鏡像可以是任何有效鏡像。
官方建議,如果只需要一個linux基礎鏡像,建議使用Debian鏡像,控制的很小。

FROM <image> [AS <name>]或FROM <image>[:<tag>] [AS <name>]或FROM <image>[@<digest>] [AS <name>]

LABEL

LABEL <key>=<value> <key>=<value> <key>=<value> ...

該LABEL指令將中繼資料添加到映像。A LABEL是一個索引值對。要在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."

映像可以有多個標籤。要指定多個標籤,Docker建議LABEL在可能的情況下將標籤組合到單個指令中。每個LABEL指令產生一個新的層

LABEL multi.label1="value1" multi.label2="value2" other="value3"或LABEL multi.label1="value1" \      multi.label2="value2" \      other="value3"

要查看映像的標籤,請使用docker inspect命令。

$ docker inspect Ubuntu

RUN

如果你需要RUN多個命令,建議使用多行寫出來,使用( \ )分隔多行

RUN有兩種形式

  • RUN <command> shell形式,命令在shell中運行,預設為/bin/sh
  • RUN ["executable", "param1", "param2"]
    RUN指令在當前鏡像的頂部的新層中執行任何命令,病提交結果,結果提交的映像當被使用者下一步Dockerfile

可以使用命令更改shell中的預設的SHELL.

在shell表單中,可以使用 \ 講一條指令繼續下一行
例如:

RUN /bin/bash -c 'source $HOME/.bashrc; \echo $HOME'

相當於:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'

註:如果你想使用其他shell比如bash,請使用在所需的shell傳遞參數,RUN ["/bin/bash", "-c", "echo hello"]

apt-get

如果你的基礎鏡像使用的是Debian,那你一定會經常使用apt-get命令安裝軟體

一般來說,我們最好不要使用apt-get upgrade或者apt-get dist-upgrade,使用上述命令會造成許多非必須包被安裝,這是不必要的。如果知道要更新當前基礎鏡像中中的某一個軟體,比如nginx,請使用apt-get install -y nginx來進行安裝更新

通常我們會如下使用他:

RUN apt-get update && apt-get install -y \        package-bar \        package-baz \        package-foo

先執行apt-get update是為了確保不被緩衝所幹擾,保證安裝的軟體是比較新的版本。

以下是一個使用RUNapt-get的一個例子:

RUN apt-get update && apt-get install -y \    aufs-tools \    automake \    build-essential \    curl \    dpkg-sig \    libcap-dev \    libsqlite3-dev \    mercurial \    reprepro \    ruby1.9.1 \    ruby1.9.1-dev \    s3cmd=1.1.* \ && rm -rf /var/lib/apt/lists/*

最後刪除/var/lib/apt/lists/是為了清理緩衝從而減少鏡像大小,Debian和Ubuntu都會在最後自動調用apt-get clean*來清理,不需要顯示調用

CMD

該指令有三種形式:

  • CMD ["executable","param1","param2"],這是首先方式
  • CMD ["param1","param2"],作為ENTRYPOINT的預設參數
  • CMD command param1 param2 外殼形式

當以shell或者exec格式使用是,該CMD指令設定運行鏡像時要執行的命令
如果你使用shell的形式CMD,那麼<command>將執行 /bin/sh -c:

FROM ubuntuCMD echo "This is a test." | wc -

如果您想在 <command> 沒有shell 的情況下運行,那麼您必須將該命令表達為JSON數組,並提供可執行檔的完整路徑。 此數組形式是首選格式CMD。任何其他參數必須單獨表示為數組中的字串:

FROM ubuntuCMD ["/usr/bin/wc","--help"]

CMD指令應用與運行鏡像中所包含的軟體,及其參數。CMD應該以CMD [“executable”, “param1”, “param2”…]表示。

在很多時候,CMD給出的是一個互動式shell,比如bash,Python等,比如CMD ["perl", "-de0"]CMD ["python"],或 CMD [“php”, “-a”]

EXPOSE

該指令指示容器講監聽連結的連接埠,類似於,將容器中的某一個連接埠暴露出去,從而在外部存取綁定該連接埠。在容器內部,應該使用應用的傳統通用連接埠。

EXPOSE <port> [<port>...]

該EXPOSE指令通知Docker容器在運行時監聽指定的網路連接埠。EXPOSE不使主機的連接埠可以訪問。為此,您必須使用該-p標誌來發布一系列連接埠,或者使用該-P標誌來發布所有暴露的連接埠。您可以公開一個連接埠號碼,並在外部發布另一個連接埠號碼

ENV

ENV <key> <value>ENV <key>=<value> ...

註:

  • 該ENV指令將環境變數<key>設定為該值 <value>。該值將處於所有“後代” Dockerfile命令的環境中
  • 該ENV指令有兩種形式。第一個表單ENV <key> <value>將會將一個變數設定為一個值。第一個空格後的整個字串將被視為<value>- 包括空格和引號等字元。
  • 第二種形式ENV <key>=<value> ...允許一次設定多個變數。請注意,第二種形式在文法中使用等號(=),而第一種形式則不使用等號。像命令列解析一樣,引號和反斜線可用於在值中包含空格。

例如:

ENV myName John DoeENV myDog Rex The DogENV myCat fluffy和ENV myName="John Doe" myDog=Rex\ The\ Dog \    myCat=fluffy

上述兩種方法所產生的結果是一樣的,推薦使用第一種方式。

使用ENV來更新容器中的環境變數PATH,例如:ENV PATH /usr/local/nginx/bin:$PATH將確保CMD [“nginx”]工作正常。

ENV指令用於提供特定服務所需要的環境變數

ENV指令還可以用來設定常用的版本號碼,使其更方便維護,例子如下:

ENV PG_MAJOR 9.3ENV PG_VERSION 9.3.4RUN 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 or COPY

上述兩個指令的功能上是類似的,都是複製檔案到容器中。

COPY只支援講本地檔案複製到容器中
ADD不但支援講本地檔案複製到容器中,還支援本地提取檔案和遠程url下載

所以ADD最適合的恰當的使用就是講壓縮檔提取到容器中。如ADD rootfs.tar.xz /

COPY可以多次使用,例如下列例子可以使RUN快取無效判定的數量減少:

COPY requirements.txt /tmp/RUN pip install --requirement /tmp/requirements.txtCOPY . /tmp/

ADD不鼓勵使用遠程url並提取包。應該使用wget或者curl替代。可以在解壓完成之後刪除不需要的壓縮包。
以下做法是正確的範例:

RUN mkdir -p /usr/src/things \    && curl -SL http://example.com/big.tar.xz \    | tar -xJC /usr/src/things \    && make -C /usr/src/things all

對於不需要提取檔案的操作,我們應該均使用COPY來進行檔案複製操作。

ADD

該指令有兩種方式

  • ADD <src>...<dest>
  • ["<src>",... "<dest>"]

ADD指令將複製新檔案,目錄或遠程檔案URL <src> ,並將其添加到路徑中映像的檔案系統<dest>

<src>可以指定多個資源,但如果它們是檔案或目錄,則它們必須相對於正在構建的來源目錄(構建的上下文)。

每個<src>可能包含萬用字元,並使用Go的filepath.Match規則進行匹配 。例如

ADD hom* /mydir/        # adds all files starting with "hom"ADD hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

<dest>是一個絕對路徑,或相對於一個路徑WORKDIR,到其中的源將在目標容器內進行複製

ADD test relativeDir/          # adds "test" to `WORKDIR`/relativeDir/ADD test /absoluteDir/         # adds "test" to /absoluteDir/

當添加包含特殊字元(如[ 和])的檔案或目錄時,需要按照Golang規則轉義這些路徑,以防止它們被視為匹配模式。例如,要添加一個名為的檔案arr[0].txt,請使用以下命令:

ADD arr[[]0].txt /mydir/    # copy a file named "arr[0].txt" to /mydir/

COPY

同樣COPY也有兩種形式:

  • COPY <src>... <dest>
  • COPY ["<src>",... "<dest>"] (此表單是包含空格的路徑所必需的)

COPY指令將複製新檔案或目錄<src ,並將其添加到該路徑上容器的檔案系統<dest>

其他內容參見ADD部分

ENTRYPOINT

該指令也有兩種形式:

  • ENTRYPOINT ["executable", "param1", "param2"] (首選)
  • ENTRYPOINT command param1 param2 (外殼形式)

ENTRYPOINT允許你配置作為可執行檔啟動並執行容器

例如,以下將使用預設內容啟動nginx,在連接埠80上偵聽:

docker run -i -t --rm -p 80:80 nginx

執行from ENTRYPOINT例子

您可以使用exec形式ENTRYPOINT設定相當穩定的預設命令和參數,然後使用任何一種形式CMD來設定更有可能更改的其他預設值。

FROM ubuntuENTRYPOINT ["top", "-b"]CMD ["-c"]

運行容器時,您可以看到這top是唯一的過程:

$ docker run -it --rm --name test  top -Htop - 08:25:00 up  7:27,  0 users,  load average: 0.00, 0.01, 0.05Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie%Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 stKiB Mem:   2056668 total,  1616832 used,   439836 free,    99352 buffersKiB Swap:  1441840 total,        0 used,  1441840 free.  1324440 cached Mem  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND    1 root      20   0   19744   2336   2080 R  0.0  0.1   0:00.04 top

執行外殼形式的 ENTRYPOINT例子

您可以指定一個純粹的字串,ENTRYPOINT並在其中執行/bin/sh -c。此表單將使用shell處理來替換shell環境變數,並將忽略任何CMD或docker run命令列參數。為了確保能夠正確地docker stop發出任何長時間啟動並執行ENTRYPOINT可執行檔,您需要記住啟動它exec:

FROM ubuntuENTRYPOINT exec top -b

運行此鏡像時,您將看到單個PID 1過程:

$ docker run -it --rm --name test topMem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cachedCPU:   5% usr   0% sys   0% nic  94% idle   0% io   0% irq   0% sirqLoad average: 0.08 0.03 0.05 2/98 6  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND    1     0 root     R     3164   0%   0% top -b

該指令最恰當的使用者是社會鏡像的主要命令,允許該鏡像像該命令一樣運行,然後使用CMD作為預設標誌

ENTRYPOINT ["s3cmd"]CMD ["--help"]

我們可以輸入以下命令來顯示命令的協助

$ docker run s3cmd

使用正確的參數執行該命令:

$ docker run s3cmd ls s3://mybucket

VOLUME

該指令用於公開暴露容器所建立的任何資料存放區地區,配置隱藏檔或者檔案夾。使用VOLUME指令配置任何可變的或是使用者可維護的部分。

VOLUME ["/data"]

該VOLUME指令將建立具有指定名稱的安裝點,並將其標記為從本機主機或其他容器儲存外部安裝的卷。該值可以是JSON數組,VOLUME ["/var/log/"]或具有多個參數的純字串,例如VOLUME /var/log或VOLUME /var/log /var/db

USER

該指令用於配置運行服務的使用者,一般使用者將普通使用者更改我root使用者,解決許可權不足的問題

USER <user>[:<group>] orUSER <UID>[:<GID>]

該USER指令設定使用者名稱(或UID)和可選的使用者組(或GID)在運行映像時使用RUN

注:當使用者沒有主組時,將使用該root組運行映像

WORKDIR

WORKDIR /path/to/workdir

該指令用於配置工作目錄,其參數應該使用絕對目錄。該命令其實也就是RUN cd … && do-something的變體。使其更清楚

該WORKDIR指令可以在一次使用多次Dockerfile。如果提供了相對路徑,它將相對於上一條WORKDIR指令的路徑 。例如:

WORKDIR /aWORKDIR bWORKDIR cRUN pwd

最終pwd命令的輸出Dockerfile就是這樣 /a/b/c

ARG

ARG <name>[=<default value>]

該ARG指令定義了使用者可以docker build使用該--build-arg <varname>=<value> 標誌使用命令在構建時傳遞給構建器的變數。如果使用者指定了在Dockerfile中未定義的構建參數,則構建會輸出警告[Warning] One or more build-args [foo] were not consumed.

Docker檔案可以包括一個或多個ARG指令。例如,以下是一個有效Docker檔案

FROM busyboxARG user1ARG buildno...

ARG預設值

ARG指令可以可選地包括一個預設值

FROM busyboxARG user1=someuserARG buildno=1...

如果ARG指令具有預設值,並且如果在構建時沒有傳遞任何值,則構建器將使用預設值。

ONBUILD

該指令在當前Dockerfile構建完成後執行。ONBUILD在匯出FROM當前映像的任何子映像中執行。將該ONBUILD命令視為父母Dockerfile給予孩子的指示Dockerfile。

註:

  • ddocker Version: 17.05.0-ce
  • docker-machine version 0.12.2, build 9371605
  • 上述環境在ubuntu16.04 lts中搭建測試成功
  • 上述文字皆為個人看法,如有錯誤或建議請及時聯絡我
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.