docker之dockerfile

1. dockerfile 是什麼 ?

1. 定義

​ dockerfile 是用來構建 Docker 鏡像的構建文件,是由一系列命令和參數構成的腳本

2. 文件實例

以 centos 爲例

FROM scratch
ADD centos-8-container.tar.xz /

LABEL org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20190927"

CMD ["/bin/bash"]

3. dockerfile、Docker 鏡像和 Docker 容器的關係

從應用軟件的角度來看,Dockerfile、Docker 鏡像、Docker 容器分別代表軟件開發的三個階段

  • Dockerfile 是軟件的原材料,包括執行代碼、文件、環境變量、依賴包、運行時環境等,面向開發
  • Docker 鏡像是軟件的交付品,由 dockerfile 文件運行 docker build 指令生成,成爲交付標準
  • Docker 容器可以認爲是軟件的運行態,當運行 Docker 鏡像時,真正開始提供服務,涉及運維和部署

三者缺一不可,合力充當 Docker 體系的基石

2. dockerfile 基礎知識

1. dockerfile 語法

  1. 每條保留字指令都必須爲大寫字母且後面至少跟隨一個參數
  2. 指令按照從上到下,順序執行
  3. # 表示註釋
  4. 每條指令都會創建一個新的鏡像層,並對鏡像進行提交

2. dockerfile 執行流程

  1. docker 從基礎鏡像運行一個容器
  2. 執行一條指令並對容器進行修改
  3. 執行類似 docker commit 的操作提交一個新的鏡像層
  4. docker 再基於剛提交的鏡像運行一個新容器
  5. 執行 dockerfile 中的下一條指令直到所有指令偶執行完成

3. dockerfile 保留字指令

保留字指令 作用 備註
FROM 基礎鏡像,當前新鏡像是基於哪個鏡像的
MAINTAINER 作者+作者郵箱
RUN 鏡像構建時需要運行的命令
EXPOSE 當前容器對外暴露的端口
WORKDIR 指定創建容器後,終端默認登陸時進入的工作目錄
ENV 構建鏡像中設置環境變量
ADD 將宿主機目錄下的文件拷貝進鏡像 會自動處理URL和解壓tar
COPY 將宿主機目錄下的文件拷貝進鏡像 不會自動處理URL,也不解壓tar
VOLUME 容器數據卷,用於數據保存和持久化工作
CMD 指定一個容器啓動時要運行的命令 存在多個CMD指令,只生效最後一個,docker run 之後的參數會覆蓋原來參數
ENTRYPOINT 指定一個容器啓動時要運行的命令 存在多個ENTRYPOINT指令,只生效最後一個,docker run 之後的參數會追加到原來參數列表中
ONBUILD 當父鏡像被子鏡像繼承時,父鏡像的ONBUILD被觸發

4. dockerfile 使用案例

1. 自定義 centos 鏡像

  1. 默認 centos 鏡像情況

    1. 運行該鏡像默認進入 / 目錄
    2. 不支持 vim
    3. 不支持 ifconfig
  2. 編寫自己的 dockerfile 文件

    # 當前鏡像基於 centos 鏡像
    FROM centos
    
    # 作者+郵箱
    MAINTAINER lyy<[email protected]>
    
    # 設置環境變量
    ENV MYPATH /tmp
    
    # 設置鏡像運行落腳點
    WORKDIR $MYPATH
    
    # 運行yum命令安裝vim
    RUN yum -y install vim
    
    # 運行yum命令安裝net-tools
    RUN yum -y install net-tools
    
    # 向外暴露80端口
    EXPOSE 80
    
    # 指定容器啓動時運行的命令
    CMD /bin/bash
    
  3. 運行構建命令

    # 將 /mydocker/dockerFile 文件構建成名爲 mycentos 版本號爲 1.3 的鏡像
    docker build -f /mydocker/dockerFile -t mycentos:1.3 .
    
  4. 運行構建出的鏡像

    docker run -it mycentos:1.3
    

2. CMD 和 ENTRYPOINT 的區別

  1. 共同點

    都是指定一個容器啓動時要運行的命令,且只生效最後一個

  2. 區別

    1. 使用 CMD 作爲 dockerfile 命令

      1. 編寫 dockerFile2

        FROM centos
        RUN yum -y install curl
        CMD ["curl","-s","http://www.baidu.com"]
        
      2. 構建鏡像

        docker build -f /mydocker/dockerFile2 -t myip .
        
      3. 運行容器

        docker run myip
        

        curl 命令將 www.baidu.com 的 html 內容顯示到控制檯

        當給 curl 加上 -i 參數,表示顯示內容中加上協議頭

        當運行:

        docker run myip -i
        

        報錯:

        docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused “exec: “-i”: executable file not found in $PATH”: unknown.

    2. 使用 ENTRYPOINT 作爲 dockerfile 命令

      1. 編寫 dockerFile3

        FROM centos
        RUN yum -y install curl
        # 將 CMD 替換爲 ENTRYPOINT 
        ENTRYPOINT  ["curl","-s","http://www.baidu.com"]
        
      2. 構建鏡像

        docker build -f /mydocker/dockerFile3 -t myip2 .
        
      3. 運行容器

        docker run myip2
        

        輸出結果與前面包含 CMD 命令的 dockerfile 一致

        當運行:

        docker run myip -i
        

        正確輸出協議頭和 html 內容

    3. CMD 和 ENTRYPOINT 的區別在於,CMD 將 docker run 後面的參數替換爲要執行的參數;而 ENTRYPOINT 將 docker run 後面的參數追加到要執行的命令中

3. 自定義 tomcat9

  1. 編寫 dockerfile

    FROM centos
    
    MAINTAINER lyy<[email protected]>
    
    # 將宿主機中的文件c複製到容器中
    COPY c /usr/local/cincontainer
    
    # 解壓並拷貝tomcat和jdk
    ADD apache-tomcat-9.0.30.tar.gz /usr/local/
    ADD jdk-8u231-linux-x64.tar.gz /usr/local/
    # 運行yum安裝vim
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    
    WORKDIR $MYPATH
    # 設置環境變量
    ENV JAVA_HOME /usr/local/jdk1.8.0_231
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.30
    ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.30
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    # 暴露端口8080
    EXPOSE 8080
    # 容器啓動時運行 tomcat
    CMD /usr/local/apache-tomcat-9.0.30/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.30/bin/logs/catalina.out
    
  2. 構建鏡像

    docker build -f /mydocker/tomcat9/dockerfile -t lyytomcat9 .
    
  3. 運行容器

    docker run -d -p:7777:8080 --name myt9 
    -v /mydocker/tomcat9/test:/usr/local/apache-tomcat-9.0.30/webapps/test 
    -v /mydocker/tomcat9/tomcat9logs:/usr/local/apache-tomcat-9.0.30/logs 
    lyytomcat9
    

    -d:後臺運行

    -p:向外映射 7777 端口

    –name:重命名

    -v:添加容器卷

  4. 驗證

    curl localhost:7777
    

    正確返回 tomcat 頁面信息

    docker exec d67c82132a22 pwd
    

    正確返回容器落腳點

    docker exec d67c82132a22 java -version
    

    正確返回 jdk 版本號

參考資料:尚硅谷周陽 Docker 教程

發佈了65 篇原創文章 · 獲贊 261 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章