Dockerfile

Docker 能夠經過 Dockerfile 的內容來自動構建鏡像。Dockerfile 是一個包含建立鏡像全部命令的文本文件,經過docker build命令能夠根據 Dockerfile 的內容構建鏡像,在介紹如何構建以前先介紹下 Dockerfile 的基本語法結構。mysql

Dockerfile 有如下指令選項:nginx

  • FROM
  • MAINTAINER
  • RUN
  • CMD
  • EXPOSE
  • ENV
  • ADD
  • COPY
  • ENTRYPOINT
  • VOLUME
  • USER
  • WORKDIR
  • ONBUILD

7.1 FROM

用法:git

FROM <image>

或者github

FROM <image>
  • FROM指定構建鏡像的基礎源鏡像,若是本地沒有指定的鏡像,則會自動從 Docker 的公共庫 pull 鏡像下來。
  • FROM必須是 Dockerfile 中非註釋行的第一個指令,即一個 Dockerfile 從FROM語句開始。
  • FROM能夠在一個 Dockerfile 中出現屢次,若是有需求在一個 Dockerfile 中建立多個鏡像。
  • 若是FROM語句沒有指定鏡像標籤,則默認使用latest標籤。

7.2 MAINTAINER

用法:golang

MAINTAINER <name>

指定建立鏡像的用戶sql

RUN 有兩種使用方式docker

  • RUN
  • RUN  每條RUN指令將在當前鏡像基礎上執行指定命令,並提交爲新的鏡像,後續的RUN都在以前RUN提交後的鏡像爲基礎,鏡像是分層的,能夠經過一個鏡像的任何一個歷史提交點來建立,相似源碼的版本控制

     

    exec 方式會被解析爲一個 JSON 數組,因此必須使用雙引號而不是單引號。exec 方式不會調用一個命令 shell,因此也就不會繼承相應的變量,如:shell

    這種方式是不會達到輸出 HOME 變量的,正確的方式應該是這樣的

     

    RUN產生的緩存在下一次構建的時候是不會失效的,會被重用,可使用--no-cache選項,即docker build --no-cache,如此便不會緩存。

     

    7.3 CMD

    CMD有三種使用方式:數據庫

    7.7 COPY

    COPY <src>... <dest>

    COPY複製新文件或者目錄從 而且添加到容器指定路徑中 。用法同ADD,惟一的不一樣是不能指定遠程文件 URLS。

    7.8 ENTRYPOINT

    • ENTRYPOINT  配置容器啓動後執行的命令,而且不可被 docker run 提供的參數覆蓋,而CMD是能夠被覆蓋的。若是須要覆蓋,則可使用docker run --entrypoint選項。

       

      每一個 Dockerfile 中只能有一個ENTRYPOINT,當指定多個時,只有最後一個生效。

      Exec form ENTRYPOINT 例子

      經過ENTRYPOINT使用 exec form 方式設置穩定的默認命令和選項,而使用CMD添加默認以外常常被改動的選項。

      經過 Dockerfile 使用ENTRYPOINT展現前臺運行 Apache 服務

       

      FROM debian:stable
      RUN apt-get update && apt-get install -y --force-yes apache2
      EXPOSE 80 443
      VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
      ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

      Shell form ENTRYPOINT 例子

      這種方式會在/bin/sh -c中執行,會忽略任何CMD或者docker run命令行選項,爲了確保docker stop可以中止長時間運行ENTRYPOINT的容器,確保執行的時候使用exec選項。

      若是在ENTRYPOINT忘記使用exec選項,則可使用CMD補上:

       

      
      7.9 VOLUME
      建立一個能夠從本地主機或其餘容器掛載的掛載點,後續具體介紹。

       

      7.10 USER

      指定運行容器時的用戶名或 UID,後續的RUN、CMD、ENTRYPOINT也會使用指定用戶。

       

      7.11 WORKDIR

      爲後續的RUN、CMD、ENTRYPOINT指令配置工做目錄。可使用多個WORKDIR指令,後續命令若是參數是相對路徑,則會基於以前命令指定的路徑。

       

      最終路徑是/a/b/c。

       

      WORKDIR指令能夠在ENV設置變量以後調用環境變量:

      最終路徑則爲 /path/$DIRNAME。

       

      7.12 ONBUILD

      配置當所建立的鏡像做爲其它新建立鏡像的基礎鏡像時,所執行的操做指令。

       

      例如,Dockerfile 使用以下的內容建立了鏡像 image-A:

      若是基於 image-A 建立新的鏡像時,新的 Dockerfile 中使用 FROM image-A 指定基礎鏡像時,會自動執行 ONBUILD 指令內容,等價於在後面添加了兩條指令。

       

      使用ONBUILD指令的鏡像,推薦在標籤中註明,例如 ruby:1.9-onbuild。

       

      7.13 Dockerfile Examples

      # 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.

      7.14 docker build

      參考文檔:
      7.15 dockerfile 最佳實踐
      • 使用.dockerignore文件

      爲了在docker build過程當中更快上傳和更加高效,應該使用一個.dockerignore文件用來排除構建鏡像時不須要的文件或目錄。例如,除非.Git在構建過程當中須要用到,不然你應該將它添加到.dockerignore文件中,這樣能夠節省不少時間。

      • 避免安裝沒必要要的軟件包

      爲了下降複雜性、依賴性、文件大小以及構建時間,應該避免安裝額外的或沒必要要的包。例如,不須要在一個數據庫鏡像中安裝一個文本編輯器。

      • 每一個容器都跑一個進程

      在大多數狀況下,一個容器應該只單獨跑一個程序。解耦應用到多個容器使其更容易橫向擴展和重用。若是一個服務依賴另一個服務,能夠參考 

       
                       
    • 最小化層

    咱們知道每執行一個指令,都會有一次鏡像的提交,鏡像是分層的結構,對於Dockerfile,應該找到可讀性和最小化層之間的平衡。

    • 多行參數排序

    若是可能,經過字母順序來排序,這樣能夠避免安裝包的重複而且更容易更新列表,另外可讀性也會更強,添加一個空行使用\換行:

    RUN apt-get update && apt-get install -y \
      bzr \
      cvs \
      git \
      mercurial \
      subversion
    • 建立緩存

    鏡像構建過程當中會按照Dockerfile的順序依次執行,每執行一次指令 Docker 會尋找是否有存在的鏡像緩存可複用,若是沒有則建立新的鏡像。若是不想使用緩存,則能夠在docker build時添加--no-cache=true選項。

    從基礎鏡像開始就已經在緩存中了,下一個指令會對比全部的子鏡像尋找是否執行相同的指令,若是沒有則緩存失效。在大多數狀況下只對比Dockerfile指令和子鏡像就足夠了。ADD和COPY指令除外,執行ADD和COPY時存放到鏡像的文件也是須要檢查的,完成一個文件的校驗以後再利用這個校驗在緩存中查找,若是檢測的文件改變則緩存失效。RUN apt-get -y update命令只檢查命令是否匹配,若是匹配就不會再執行更新了。

    爲了有效地利用緩存,你須要保持你的 Dockerfile 一致,而且儘可能在末尾修改。

     

    Dockerfile 指令

    • FROM: 只要可能就使用官方鏡像庫做爲基礎鏡像
    • RUN: 爲保持可讀性、方便理解、可維護性,把長或者複雜的RUN語句使用\分隔符分紅多行
      • 不建議RUN apt-get update獨立成行,不然若是後續包有更新,那麼也不會再執行更新
      • 避免使用RUN apt-get upgrade或者dist-upgrade,不少必要的包在一個非privileged權限的容器裏是沒法升級的。若是知道某個包更新,使用apt-get install -y xxx
      • 標準寫法
        • RUN apt-get update && apt-get install -y package-bar package-foo

    例子:

    RUN apt-get update && apt-get install -y \
        aufs-tools \
        automake \
        btrfs-tools \
        build-essential \
        curl \
        dpkg-sig \
        git \
        iptables \
        libapparmor-dev \
        libcap-dev \
        libsqlite3-dev \
        lxc=1.0* \
        mercurial \
        parallel \
        reprepro \
        ruby1.9.1 \
        ruby1.9.1-dev \
        s3cmd=1.1.0*
    • CMD: 推薦使用CMD [「executable」, 「param1」, 「param2」…]這種格式,CMD [「param」, 「param」]則配合ENTRYPOINT使用
    • EXPOSE: Dockerfile 指定要公開的端口,使用docker run時指定映射到宿主機的端口便可
    • ENV: 爲了使新的軟件更容易運行,可使用ENV更新PATH變量。如ENV PATH /usr/local/nginx/bin:$PATH確保CMD ["nginx"]便可運行

    ENV也能夠這樣定義變量:

    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
    • ADDorCOPY:ADD比COPY多一些特性「tar 文件自動解包和支持遠程 URL」,不推薦添加遠程 URL

    如不推薦這種方式:

    推薦使用 curl 或者 wget 替換,使用以下方式:

     

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

    若是不須要添加 tar 文件,推薦使用COPY。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息