文章目錄
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 語法
- 每條保留字指令都必須爲大寫字母且後面至少跟隨一個參數
- 指令按照從上到下,順序執行
- # 表示註釋
- 每條指令都會創建一個新的鏡像層,並對鏡像進行提交
2. dockerfile 執行流程
- docker 從基礎鏡像運行一個容器
- 執行一條指令並對容器進行修改
- 執行類似 docker commit 的操作提交一個新的鏡像層
- docker 再基於剛提交的鏡像運行一個新容器
- 執行 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 鏡像
-
默認 centos 鏡像情況
- 運行該鏡像默認進入 / 目錄
- 不支持 vim
- 不支持 ifconfig
-
編寫自己的 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
-
運行構建命令
# 將 /mydocker/dockerFile 文件構建成名爲 mycentos 版本號爲 1.3 的鏡像 docker build -f /mydocker/dockerFile -t mycentos:1.3 .
-
運行構建出的鏡像
docker run -it mycentos:1.3
2. CMD 和 ENTRYPOINT 的區別
-
共同點
都是指定一個容器啓動時要運行的命令,且只生效最後一個
-
區別
-
使用 CMD 作爲 dockerfile 命令
-
編寫 dockerFile2
FROM centos RUN yum -y install curl CMD ["curl","-s","http://www.baidu.com"]
-
構建鏡像
docker build -f /mydocker/dockerFile2 -t myip .
-
運行容器
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.
-
-
使用 ENTRYPOINT 作爲 dockerfile 命令
-
編寫 dockerFile3
FROM centos RUN yum -y install curl # 將 CMD 替換爲 ENTRYPOINT ENTRYPOINT ["curl","-s","http://www.baidu.com"]
-
構建鏡像
docker build -f /mydocker/dockerFile3 -t myip2 .
-
運行容器
docker run myip2
輸出結果與前面包含 CMD 命令的 dockerfile 一致
當運行:
docker run myip -i
正確輸出協議頭和 html 內容
-
-
CMD 和 ENTRYPOINT 的區別在於,CMD 將 docker run 後面的參數替換爲要執行的參數;而 ENTRYPOINT 將 docker run 後面的參數追加到要執行的命令中
-
3. 自定義 tomcat9
-
編寫 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
-
構建鏡像
docker build -f /mydocker/tomcat9/dockerfile -t lyytomcat9 .
-
運行容器
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:添加容器卷
-
驗證
curl localhost:7777
正確返回 tomcat 頁面信息
docker exec d67c82132a22 pwd
正確返回容器落腳點
docker exec d67c82132a22 java -version
正確返回 jdk 版本號
參考資料:尚硅谷周陽 Docker 教程