<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    方槍槍的java世界

    不要因為風雨飄落就停止了你的腳步,真正的得失就在你的心中。 做喜歡做的事,不輕言放棄!

    Docker學習筆記(五)Dockerfile

    七、Dockerfile

    Docker 可以通過 Dockerfile 的內容來自動構建鏡像。Dockerfile 是一個包含創建鏡像所有命令的文本文件,通過docker build命令可以根據 Dockerfile 的內容構建鏡像,在介紹如何構建之前先介紹下 Dockerfile 的基本語法結構。

    Dockerfile 有以下指令選項:

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

    7.1 FROM

    用法:

    FROM <image>

    或者

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

    7.2 MAINTAINER

    用法:

    MAINTAINER <name>

    指定創建鏡像的用戶

    RUN 有兩種使用方式

    • RUN
    • RUN

    每條RUN指令將在當前鏡像基礎上執行指定命令,并提交為新的鏡像,后續的RUN都在之前RUN提交后的鏡像為基礎,鏡像是分層的,可以通過一個鏡像的任何一個歷史提交點來創建,類似源碼的版本控制。

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

    RUN [ "echo", "$HOME" ]

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

    RUN [ "sh", "-c", "echo", "$HOME" ]

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

    7.3 CMD

    CMD有三種使用方式:

    CMD指定在 Dockerfile 中只能使用一次,如果有多個,則只有最后一個會生效。

    CMD的目的是為了在啟動容器時提供一個默認的命令執行選項。如果用戶啟動容器時指定了運行的命令,則會覆蓋掉CMD指定的命令。

    CMD會在啟動容器的時候執行,build 時不執行,而RUN只是在構建鏡像的時候執行,后續鏡像構建完成之后,啟動容器就與RUN無關了,這個初學者容易弄混這個概念,這里簡單注解一下。

    7.4 EXPOSE

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

    告訴 Docker 服務端容器對外映射的本地端口,需要在 docker run 的時候使用-p或者-P選項生效。

    7.5 ENV

    ENV <key> <value>       # 只能設置一個變量
    ENV <key>=<value> ...   # 允許一次設置多個變量

    指定一個環節變量,會被后續RUN指令使用,并在容器運行時保留。

    例子:

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

    等同于

    ENV myName John Doe
    ENV myDog Rex The Dog
    ENV myCat fluffy

    7.6 ADD

    ADD <src>... <dest>

    ADD復制本地主機文件、目錄或者遠程文件 URLS 從 并且添加到容器指定路徑中 。

    支持通過 GO 的正則模糊匹配,具體規則可參見 Go filepath.Match

    ADD hom* /mydir/        # adds all files starting with "hom"
    ADD hom?.txt /mydir/    # ? is replaced with any single character
    • 路徑必須是絕對路徑,如果 不存在,會自動創建對應目錄
    • 路徑必須是 Dockerfile 所在路徑的相對路徑
    • 如果是一個目錄,只會復制目錄下的內容,而目錄本身則不會被復制

    7.7 COPY

    COPY <src>... <dest>

    COPY復制新文件或者目錄從 并且添加到容器指定路徑中 。用法同ADD,唯一的不同是不能指定遠程文件 URLS。

    7.8 ENTRYPOINT

    配置容器啟動后執行的命令,并且不可被 docker run 提供的參數覆蓋,而CMD是可以被覆蓋的。如果需要覆蓋,則可以使用docker run --entrypoint選項。

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

    Exec form ENTRYPOINT 例子

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

    FROM ubuntu
    ENTRYPOINT ["top", "-b"]
    CMD ["-c"]

    通過 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選項。

    FROM ubuntu
    ENTRYPOINT exec top -b

    如果在ENTRYPOINT忘記使用exec選項,則可以使用CMD補上:

    FROM ubuntu
    ENTRYPOINT top -b
    CMD --ignored-param1 # --ignored-param2 ... --ignored-param3 ... 依此類推

    7.9 VOLUME

    VOLUME ["/data"]

    創建一個可以從本地主機或其他容器掛載的掛載點,后續具體介紹。

    7.10 USER

    USER daemon

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

    7.11 WORKDIR

    WORKDIR /path/to/workdir

    為后續的RUN、CMD、ENTRYPOINT指令配置工作目錄。可以使用多個WORKDIR指令,后續命令如果參數是相對路徑,則會基于之前命令指定的路徑。

    WORKDIR /a
    WORKDIR b
    WORKDIR c
    RUN pwd

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

    WORKDIR指令可以在ENV設置變量之后調用環境變量:

    ENV DIRPATH /path
    WORKDIR $DIRPATH/$DIRNAME

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

    7.12 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 指令內容,等價于在后面添加了兩條指令。

    # Automatically run the following
    ADD . /app/src
    RUN /usr/local/bin/python-build --dir /app/src

    使用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

    $ docker build --help
    
    Usage: docker build [OPTIONS] PATH | URL | -
    
    Build a new image from the source code at PATH
    
      --force-rm=false     Always remove intermediate containers, even after unsuccessful builds # 移除過渡容器,即使構建失敗
      --no-cache=false     Do not use cache when building the image                              # 不實用 cache        
      -q, --quiet=false    Suppress the verbose output generated by the containers               
      --rm=true            Remove intermediate containers after a successful build               # 構建成功后移除過渡層容器
      -t, --tag=""         Repository name (and optionally a tag) to be applied to the resulting image in case of success

    參考文檔:Dockerfile Reference

    7.15 dockerfile 最佳實踐

    • 使用.dockerignore文件

    為了在docker build過程中更快上傳和更加高效,應該使用一個.dockerignore文件用來排除構建鏡像時不需要的文件或目錄。例如,除非.git在構建過程中需要用到,否則你應該將它添加到.dockerignore文件中,這樣可以節省很多時間。

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

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

    • 每個容器都跑一個進程

    在大多數情況下,一個容器應該只單獨跑一個程序。解耦應用到多個容器使其更容易橫向擴展和重用。如果一個服務依賴另外一個服務,可以參考 Linking Containers Together

    • 最小化層

    我們知道每執行一個指令,都會有一次鏡像的提交,鏡像是分層的結構,對于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

    如不推薦這種方式:

    ADD http://example.com/big.tar.xz /usr/src/things/
    RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
    RUN make -C /usr/src/things all

    推薦使用 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。

    參考文檔:

    posted on 2016-12-27 21:35 做強大的自己 閱讀(130) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产亚洲精品国产福利在线观看| 亚洲春色另类小说| 色婷婷综合缴情综免费观看 | 亚洲日韩欧洲无码av夜夜摸| 特级毛片在线大全免费播放| 国产男女猛烈无遮挡免费网站| 亚洲乱人伦中文字幕无码| 影音先锋在线免费观看| 亚洲色偷偷色噜噜狠狠99| 日本一道在线日本一道高清不卡免费| 亚洲一区二区三区高清在线观看| 免费理论片51人人看电影| 亚洲AV日韩AV一区二区三曲| 免费国产综合视频在线看| 国产精品无码永久免费888 | 亚洲国产人成网站在线电影动漫| 亚在线观看免费视频入口| 亚洲第一二三四区| 大地资源免费更新在线播放| 亚洲av第一网站久章草| 亚洲第一成人影院| a级成人毛片免费视频高清| 久久亚洲精品无码| 日韩版码免费福利视频| 美女18毛片免费视频| 久久久亚洲精品蜜桃臀| 97精品免费视频| 狠狠入ady亚洲精品| 亚洲片国产一区一级在线观看| 免费视频成人手机在线观看网址| 亚洲国产精品综合久久20| 日本中文一区二区三区亚洲| 久久九九免费高清视频| 在线亚洲高清揄拍自拍一品区| 国产成人无码免费看视频软件| 色噜噜的亚洲男人的天堂| 国产亚洲真人做受在线观看| 亚洲一级免费毛片| 免费国产草莓视频在线观看黄| 亚洲AV永久无码精品| 成人毛片视频免费网站观看|