Dockerfile 是用來構建 Docker 鏡像的構建文件,是由一系列命令和參數構成的腳本。
以 CentOS 為例(https://hub.docker.com/_/centos):

FROM centos:7 ENV container docker RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \ systemd-tmpfiles-setup.service ] || rm -f $i; done); \ rm -f /lib/systemd/system/multi-user.target.wants/*;\ rm -f /etc/systemd/system/*.wants/*;\ rm -f /lib/systemd/system/local-fs.target.wants/*; \ rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ rm -f /lib/systemd/system/basic.target.wants/*;\ rm -f /lib/systemd/system/anaconda.target.wants/*; VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"]
一、Dockerfile 介紹
1.基礎知識
- 每條保留字指令都必須為大寫字母且后面要跟隨至少一個參數
- 指令按照從上到下,順序執行
- # 表示注釋
- 每條指令都會創建一個新的鏡像層,並對鏡像進行提交
2.Docker 執行 DockerFile 的大致流程
- docker 從基礎鏡像運行一個容器
- 執行一條指令並對容器作出修改
- 執行類似 docker commit 的操作提交一個新的鏡像層
- docker 再基於剛提交的鏡像運行一個新容器
- 執行 dockerfile 中的下一條指令直到所有指令都執行完成
3.DockerFile 體系結構(保留字指令)
FROM:基礎鏡像,當前新鏡像是基於哪個鏡像的 MAINTAINER:鏡像維護者的姓名和郵箱地址 RUN:容器構建時需要運行的命令 EXPOSE:當前容器對外暴露出的端口 WORKDIR:指定在創建容器后,終端默認登陸的進來工作目錄,一個落腳點 ENV:用來在構建鏡像過程中設置環境變量 ADD:將宿主機目錄下的文件拷貝進鏡像且 ADD 命令會自動處理 URL 和解壓 tar 壓縮包 COPY:類似 ADD,拷貝文件和目錄到鏡像中。(COPY src dest 或 COPY ["src","dest"]) VOLUME:容器數據卷,用於數據保存和持久化工作 CMD:指定一個容器啟動時要運行的命令,Dockerfile 中可以有多個 CMD 指令,但只有最后一個生效,CMD 會被 docker run 之后的參數替換 ENTRYPOINT:指定一個容器啟動時要運行的命令,ENTRYPOINT 的目的和 CMD 一樣,都是在指定容器啟動程序及參數 ONBUILD:當構建一個被繼承的 Dockerfile 時運行命令,父鏡像在被子繼承后父鏡像的 onbuild 被觸發
二、自定義鏡像
Docker Hub 中 99% 的鏡像都是通過在 base 鏡像中安裝和配置需要的軟件構建出來的,如:FROM scratch、FROM centos
1.定制 centos
使自己的鏡像具備:登陸后的默認路徑、vim 編輯器、查看網絡配置 ifconfig 支持
dockerfile 文件
FROM centos MAINTAINER jhxxb ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "success--------------ok" CMD /bin/bash
執行構建
# . 表示當前路徑 docker build -f mydockerfile -t mycentos:0.1 .
驗證是否支持所需功能
查看鏡像變更歷史
docker history mycentos:0.1
2.CMD 與 ENTRYPOINT
Dockerfile 中可以有多個 CMD 指令,但只有最后一個生效,CMD 會被 docker run 之后的參數替換。
dockerfile 文件
FROM centos RUN yum install -y curl CMD [ "curl", "-s", "https://ip.cn" ]
如果我們希望顯示 HTTP 頭信息,就需要加上 -i 參數,但這樣運行帶參數的命令會出錯。
因為跟在鏡像名后面的是 command,運行時會替換 CMD 的默認值。因此這里的 -i 替換了原來的 CMD,而不是添加在原來的 curl -s https://ip.cn 后面。而 -i 根本不是命令,所以自然找不到。
docker build -f mydockerfile -t myip:0.1 . docker run myip:0.1 -i
解決方法有兩種
輸入完整命令
docker run myip:0.1 curl -s https://ip.cn -i
使用 ENTRYPOINT 構建,這樣就可以直接使用 docker run myip:0.1 -i 運行了
FROM centos RUN yum install -y curl ENTRYPOINT [ "curl", "-s", "https://ip.cn" ]
3.自定義 Tomcat9 鏡像
環境准備
dockerfile 文件
FROM centos MAINTAINER jhxxb # 把宿主機當前目錄下的 jdk1.8.0_221 拷貝到容器 /usr/local/ 路徑下 COPY jdk1.8.0_221/ /usr/local/jdk1.8.0_221/ # 把宿主機當前目錄下的 tomcat 添加到容器 /usr/local/ 路徑下 ADD apache-tomcat-9.0.24.tar.gz /usr/local/ # 安裝vim編輯器 RUN yum -y install vim # 設置工作訪問時候的 WORKDIR 路徑,登錄落腳點 ENV MYPATH /usr/local WORKDIR $MYPATH # 配置 java 與 tomcat 環境變量 ENV JAVA_HOME /usr/local/jdk1.8.0_221 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.24 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.24 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin # 容器運行時監聽的端口 EXPOSE 8080 # 啟動時運行 tomcat # ENTRYPOINT ["/usr/local/apache-tomcat-9.0.24/bin/startup.sh" ] CMD ["/usr/local/apache-tomcat-9.0.24/bin/catalina.sh","run"] # CMD /usr/local/apache-tomcat-9.0.24/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.24/bin/logs/catalina.out
在資源目錄下執行構建
docker build -f mydockerfile -t mytomcat:0.1 .
運行查看效果
docker run -d -p 9080:8080 --name myt9 -v /tmp/tomcat9logs/:/usr/local/apache-tomcat-9.0.24/logs --privileged=true mytomcat:0.1