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

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

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

    方槍槍的java世界

    不要因?yàn)轱L(fēng)雨飄落就停止了你的腳步,真正的得失就在你的心中。 做喜歡做的事,不輕言放棄!

    Docker學(xué)習(xí)筆記(五)Dockerfile

    七、Dockerfile

    Docker 可以通過 Dockerfile 的內(nèi)容來自動(dòng)構(gòu)建鏡像。Dockerfile 是一個(gè)包含創(chuàng)建鏡像所有命令的文本文件,通過docker build命令可以根據(jù) Dockerfile 的內(nèi)容構(gòu)建鏡像,在介紹如何構(gòu)建之前先介紹下 Dockerfile 的基本語法結(jié)構(gòu)。

    Dockerfile 有以下指令選項(xiàng):

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

    7.1 FROM

    用法:

    FROM <image>

    或者

    FROM <image>
    • FROM指定構(gòu)建鏡像的基礎(chǔ)源鏡像,如果本地沒有指定的鏡像,則會(huì)自動(dòng)從 Docker 的公共庫 pull 鏡像下來。
    • FROM必須是 Dockerfile 中非注釋行的第一個(gè)指令,即一個(gè) Dockerfile 從FROM語句開始。
    • FROM可以在一個(gè) Dockerfile 中出現(xiàn)多次,如果有需求在一個(gè) Dockerfile 中創(chuàng)建多個(gè)鏡像。
    • 如果FROM語句沒有指定鏡像標(biāo)簽,則默認(rèn)使用latest標(biāo)簽。

    7.2 MAINTAINER

    用法:

    MAINTAINER <name>

    指定創(chuàng)建鏡像的用戶

    RUN 有兩種使用方式

    • RUN
    • RUN

    每條RUN指令將在當(dāng)前鏡像基礎(chǔ)上執(zhí)行指定命令,并提交為新的鏡像,后續(xù)的RUN都在之前RUN提交后的鏡像為基礎(chǔ),鏡像是分層的,可以通過一個(gè)鏡像的任何一個(gè)歷史提交點(diǎn)來創(chuàng)建,類似源碼的版本控制。

    exec 方式會(huì)被解析為一個(gè) JSON 數(shù)組,所以必須使用雙引號(hào)而不是單引號(hào)。exec 方式不會(huì)調(diào)用一個(gè)命令 shell,所以也就不會(huì)繼承相應(yīng)的變量,如:

    RUN [ "echo", "$HOME" ]

    這種方式是不會(huì)達(dá)到輸出 HOME 變量的,正確的方式應(yīng)該是這樣的

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

    RUN產(chǎn)生的緩存在下一次構(gòu)建的時(shí)候是不會(huì)失效的,會(huì)被重用,可以使用--no-cache選項(xiàng),即docker build --no-cache,如此便不會(huì)緩存。

    7.3 CMD

    CMD有三種使用方式:

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

    CMD的目的是為了在啟動(dòng)容器時(shí)提供一個(gè)默認(rèn)的命令執(zhí)行選項(xiàng)。如果用戶啟動(dòng)容器時(shí)指定了運(yùn)行的命令,則會(huì)覆蓋掉CMD指定的命令。

    CMD會(huì)在啟動(dòng)容器的時(shí)候執(zhí)行,build 時(shí)不執(zhí)行,而RUN只是在構(gòu)建鏡像的時(shí)候執(zhí)行,后續(xù)鏡像構(gòu)建完成之后,啟動(dòng)容器就與RUN無關(guān)了,這個(gè)初學(xué)者容易弄混這個(gè)概念,這里簡(jiǎn)單注解一下。

    7.4 EXPOSE

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

    告訴 Docker 服務(wù)端容器對(duì)外映射的本地端口,需要在 docker run 的時(shí)候使用-p或者-P選項(xiàng)生效。

    7.5 ENV

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

    指定一個(gè)環(huán)節(jié)變量,會(huì)被后續(xù)RUN指令使用,并在容器運(yùn)行時(shí)保留。

    例子:

    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復(fù)制本地主機(jī)文件、目錄或者遠(yuǎn)程文件 URLS 從 并且添加到容器指定路徑中 。

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

    ADD hom* /mydir/        # adds all files starting with "hom"
    ADD hom?.txt /mydir/    # ? is replaced with any single character
    • 路徑必須是絕對(duì)路徑,如果 不存在,會(huì)自動(dòng)創(chuàng)建對(duì)應(yīng)目錄
    • 路徑必須是 Dockerfile 所在路徑的相對(duì)路徑
    • 如果是一個(gè)目錄,只會(huì)復(fù)制目錄下的內(nèi)容,而目錄本身則不會(huì)被復(fù)制

    7.7 COPY

    COPY <src>... <dest>

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

    7.8 ENTRYPOINT

    配置容器啟動(dòng)后執(zhí)行的命令,并且不可被 docker run 提供的參數(shù)覆蓋,而CMD是可以被覆蓋的。如果需要覆蓋,則可以使用docker run --entrypoint選項(xiàng)。

    每個(gè) Dockerfile 中只能有一個(gè)ENTRYPOINT,當(dāng)指定多個(gè)時(shí),只有最后一個(gè)生效。

    Exec form ENTRYPOINT 例子

    通過ENTRYPOINT使用 exec form 方式設(shè)置穩(wěn)定的默認(rèn)命令和選項(xiàng),而使用CMD添加默認(rèn)之外經(jīng)常被改動(dòng)的選項(xiàng)。

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

    通過 Dockerfile 使用ENTRYPOINT展示前臺(tái)運(yùn)行 Apache 服務(wù)

    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 例子

    這種方式會(huì)在/bin/sh -c中執(zhí)行,會(huì)忽略任何CMD或者docker run命令行選項(xiàng),為了確保docker stop能夠停止長(zhǎng)時(shí)間運(yùn)行ENTRYPOINT的容器,確保執(zhí)行的時(shí)候使用exec選項(xiàng)。

    FROM ubuntu
    ENTRYPOINT exec top -b

    如果在ENTRYPOINT忘記使用exec選項(xiàng),則可以使用CMD補(bǔ)上:

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

    7.9 VOLUME

    VOLUME ["/data"]

    創(chuàng)建一個(gè)可以從本地主機(jī)或其他容器掛載的掛載點(diǎn),后續(xù)具體介紹。

    7.10 USER

    USER daemon

    指定運(yùn)行容器時(shí)的用戶名或 UID,后續(xù)的RUN、CMD、ENTRYPOINT也會(huì)使用指定用戶。

    7.11 WORKDIR

    WORKDIR /path/to/workdir

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

    WORKDIR /a
    WORKDIR b
    WORKDIR c
    RUN pwd

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

    WORKDIR指令可以在ENV設(shè)置變量之后調(diào)用環(huán)境變量:

    ENV DIRPATH /path
    WORKDIR $DIRPATH/$DIRNAME

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

    7.12 ONBUILD

    ONBUILD [INSTRUCTION]

    配置當(dāng)所創(chuàng)建的鏡像作為其它新創(chuàng)建鏡像的基礎(chǔ)鏡像時(shí),所執(zhí)行的操作指令。

    例如,Dockerfile 使用如下的內(nèi)容創(chuàng)建了鏡像 image-A:

    [...]
    ONBUILD ADD . /app/src
    ONBUILD RUN /usr/local/bin/python-build --dir /app/src
    [...]

    如果基于 image-A 創(chuàng)建新的鏡像時(shí),新的 Dockerfile 中使用 FROM image-A 指定基礎(chǔ)鏡像時(shí),會(huì)自動(dòng)執(zhí)行 ONBUILD 指令內(nèi)容,等價(jià)于在后面添加了兩條指令。

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

    使用ONBUILD指令的鏡像,推薦在標(biāo)簽中注明,例如 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 # 移除過渡容器,即使構(gòu)建失敗
      --no-cache=false     Do not use cache when building the image                              # 不實(shí)用 cache        
      -q, --quiet=false    Suppress the verbose output generated by the containers               
      --rm=true            Remove intermediate containers after a successful build               # 構(gòu)建成功后移除過渡層容器
      -t, --tag=""         Repository name (and optionally a tag) to be applied to the resulting image in case of success

    參考文檔:Dockerfile Reference

    7.15 dockerfile 最佳實(shí)踐

    • 使用.dockerignore文件

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

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

    為了降低復(fù)雜性、依賴性、文件大小以及構(gòu)建時(shí)間,應(yīng)該避免安裝額外的或不必要的包。例如,不需要在一個(gè)數(shù)據(jù)庫鏡像中安裝一個(gè)文本編輯器。

    • 每個(gè)容器都跑一個(gè)進(jìn)程

    在大多數(shù)情況下,一個(gè)容器應(yīng)該只單獨(dú)跑一個(gè)程序。解耦應(yīng)用到多個(gè)容器使其更容易橫向擴(kuò)展和重用。如果一個(gè)服務(wù)依賴另外一個(gè)服務(wù),可以參考 Linking Containers Together

    • 最小化層

    我們知道每執(zhí)行一個(gè)指令,都會(huì)有一次鏡像的提交,鏡像是分層的結(jié)構(gòu),對(duì)于Dockerfile,應(yīng)該找到可讀性和最小化層之間的平衡。

    • 多行參數(shù)排序

    如果可能,通過字母順序來排序,這樣可以避免安裝包的重復(fù)并且更容易更新列表,另外可讀性也會(huì)更強(qiáng),添加一個(gè)空行使用\換行:

    RUN apt-get update && apt-get install -y \
      bzr \
      cvs \
      git \
      mercurial \
      subversion
    • 創(chuàng)建緩存

    鏡像構(gòu)建過程中會(huì)按照Dockerfile的順序依次執(zhí)行,每執(zhí)行一次指令 Docker 會(huì)尋找是否有存在的鏡像緩存可復(fù)用,如果沒有則創(chuàng)建新的鏡像。如果不想使用緩存,則可以在docker build時(shí)添加--no-cache=true選項(xiàng)。

    從基礎(chǔ)鏡像開始就已經(jīng)在緩存中了,下一個(gè)指令會(huì)對(duì)比所有的子鏡像尋找是否執(zhí)行相同的指令,如果沒有則緩存失效。在大多數(shù)情況下只對(duì)比Dockerfile指令和子鏡像就足夠了。ADD和COPY指令除外,執(zhí)行ADD和COPY時(shí)存放到鏡像的文件也是需要檢查的,完成一個(gè)文件的校驗(yàn)之后再利用這個(gè)校驗(yàn)在緩存中查找,如果檢測(cè)的文件改變則緩存失效。RUN apt-get -y update命令只檢查命令是否匹配,如果匹配就不會(huì)再執(zhí)行更新了。

    為了有效地利用緩存,你需要保持你的 Dockerfile 一致,并且盡量在末尾修改。

    Dockerfile 指令

    • FROM: 只要可能就使用官方鏡像庫作為基礎(chǔ)鏡像
    • RUN: 為保持可讀性、方便理解、可維護(hù)性,把長(zhǎng)或者復(fù)雜的RUN語句使用\分隔符分成多行
      • 不建議RUN apt-get update獨(dú)立成行,否則如果后續(xù)包有更新,那么也不會(huì)再執(zhí)行更新
      • 避免使用RUN apt-get upgrade或者dist-upgrade,很多必要的包在一個(gè)非privileged權(quán)限的容器里是無法升級(jí)的。如果知道某個(gè)包更新,使用apt-get install -y xxx
      • 標(biāo)準(zhǔn)寫法
        • 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時(shí)指定映射到宿主機(jī)的端口即可
    • ENV: 為了使新的軟件更容易運(yùn)行,可以使用ENV更新PATH變量。如ENV PATH /usr/local/nginx/bin:$PATH確保CMD ["nginx"]即可運(yùn)行

    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 文件自動(dòng)解包和支持遠(yuǎn)程 URL」,不推薦添加遠(yuǎn)程 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 做強(qiáng)大的自己 閱讀(130) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 曰韩无码AV片免费播放不卡 | 久久久久亚洲AV无码麻豆| 久久精品电影免费动漫| 亚洲欧洲日韩综合| 日韩高清免费在线观看| 4hu四虎免费影院www| 亚洲一区二区中文| 精品久久久久久久免费加勒比| 日韩在线观看视频免费| 亚洲男人第一av网站| 日韩免费高清视频| 成人性生交大片免费看中文| 亚洲欧洲日韩国产一区二区三区 | 亚洲国产视频网站| 亚洲不卡无码av中文字幕| 99久久免费精品高清特色大片| 亚洲AV日韩综合一区| 亚洲综合国产精品| 免费在线观看黄色毛片| 在线观看H网址免费入口| 一级人做人a爰免费视频| 亚洲午夜电影一区二区三区| 相泽亚洲一区中文字幕| 成人黄软件网18免费下载成人黄18免费视频 | 久久久久亚洲Av片无码v| 日本v片免费一区二区三区| 中文字幕在线观看免费视频| www免费插插视频| 精品国产亚洲一区二区三区在线观看| 久久精品国产亚洲AV无码娇色| 亚洲日韩国产成网在线观看| 国内外成人免费视频| 99免费在线观看视频| a级精品九九九大片免费看| 综合一区自拍亚洲综合图区| 亚洲午夜精品国产电影在线观看| 在线精品亚洲一区二区小说| 四虎国产精品免费视| 成人女人A级毛片免费软件| 日韩免费人妻AV无码专区蜜桃| 成人a毛片免费视频观看|