背景
Docker文件是用來構建docker鏡像的文件,由一系列命令和參數構成。
方法概述
使用三步驟:編寫docker文件、構建鏡像、運行容器
關鍵字字母必須大寫,後面必須有一個空格,以及至少一個參數。每條指令都會創建一個新的鏡像層,並對鏡像層進行提交。
dockerfile是docker鏡像的原材料,docker容器是運行着的鏡像
注意,以下dockerfile中,#後面均爲註釋,編譯時需要去掉所有註釋
例子
自定義centos的dockerfile
from centos # 指定此dockerfile是基於哪個鏡像的,至少基於scratch
ENV mypath /tmp # 定義環境變量
WORKDIR $mypath # 定義工作目錄
RUN yum -y install vim # 執行命令
RUN yum -y install net-tools
EXPOSE 80 # 暴露端口號
CMD /bin/bash # 執行最終命令,也可以使用json字符串的形式,比如CMD ["/bin/bash"]
然後編譯,-f指定dockerfile,-t指定新的鏡像名,.表示當前路徑
$ docker build -f my_centos_dockerfile -t szc_centos .
輸出如下
Sending build context to Docker daemon 4.096kB
Step 1/7 : from centos
---> 470671670cac
Step 2/7 : ENV mypath /tmp
---> Running in eaa3d946fbb4
Removing intermediate container eaa3d946fbb4
---> 8157d08e287e
Step 3/7 : WORKDIR $mypath
---> Running in 682be0d895ae
Removing intermediate container 682be0d895ae
---> c014d4c29e27
Step 4/7 : RUN yum -y install vim
---> Running in f532a2aae2c9
CentOS-8 - AppStream 1.5 MB/s | 6.5 MB 00:04
CentOS-8 - Base 294 kB/s | 5.0 MB 00:17
CentOS-8 - Extras 2.0 kB/s | 2.1 kB 00:01
Dependencies resolved.
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
vim-enhanced x86_64 2:8.0.1763-13.el8 AppStream 1.4 M
Installing dependencies:
gpm-libs x86_64 1.20.7-15.el8 AppStream 39 k
vim-common x86_64 2:8.0.1763-13.el8 AppStream 6.3 M
vim-filesystem noarch 2:8.0.1763-13.el8 AppStream 48 k
which x86_64 2.21-10.el8 BaseOS 49 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 7.8 M
Installed size: 31 M
Downloading Packages:
(1/5): gpm-libs-1.20.7-15.el8.x86_64.rpm 198 kB/s | 39 kB 00:00
(2/5): vim-filesystem-8.0.1763-13.el8.noarch.rp 868 kB/s | 48 kB 00:00
(3/5): vim-enhanced-8.0.1763-13.el8.x86_64.rpm 970 kB/s | 1.4 MB 00:01
(4/5): vim-common-8.0.1763-13.el8.x86_64.rpm 1.7 MB/s | 6.3 MB 00:03
(5/5): which-2.21-10.el8.x86_64.rpm 6.5 kB/s | 49 kB 00:07
--------------------------------------------------------------------------------
Total 908 kB/s | 7.8 MB 00:08
warning: /var/cache/dnf/AppStream-02e86d1c976ab532/packages/gpm-libs-1.20.7-15.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS-8 - AppStream 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <[email protected]>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-10.el8.x86_64 1/5
Installing : vim-filesystem-2:8.0.1763-13.el8.noarch 2/5
Installing : vim-common-2:8.0.1763-13.el8.x86_64 3/5
Installing : gpm-libs-1.20.7-15.el8.x86_64 4/5
Running scriptlet: gpm-libs-1.20.7-15.el8.x86_64 4/5
Installing : vim-enhanced-2:8.0.1763-13.el8.x86_64 5/5
Running scriptlet: vim-enhanced-2:8.0.1763-13.el8.x86_64 5/5
Running scriptlet: vim-common-2:8.0.1763-13.el8.x86_64 5/5
Verifying : gpm-libs-1.20.7-15.el8.x86_64 1/5
Verifying : vim-common-2:8.0.1763-13.el8.x86_64 2/5
Verifying : vim-enhanced-2:8.0.1763-13.el8.x86_64 3/5
Verifying : vim-filesystem-2:8.0.1763-13.el8.noarch 4/5
Verifying : which-2.21-10.el8.x86_64 5/5
Installed:
vim-enhanced-2:8.0.1763-13.el8.x86_64 gpm-libs-1.20.7-15.el8.x86_64
vim-common-2:8.0.1763-13.el8.x86_64 vim-filesystem-2:8.0.1763-13.el8.noarch
which-2.21-10.el8.x86_64
Complete!
Removing intermediate container f532a2aae2c9
---> e7e3f6dfc31b
Step 5/7 : RUN yum -y install net-tools
---> Running in 3fdcf50a41b2
Last metadata expiration check: 0:00:15 ago on Sun Mar 8 08:33:26 2020.
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
net-tools x86_64 2.0-0.51.20160912git.el8 BaseOS 323 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 323 k
Installed size: 1.0 M
Downloading Packages:
net-tools-2.0-0.51.20160912git.el8.x86_64.rpm 83 kB/s | 323 kB 00:03
--------------------------------------------------------------------------------
Total 61 kB/s | 323 kB 00:05
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : net-tools-2.0-0.51.20160912git.el8.x86_64 1/1
Running scriptlet: net-tools-2.0-0.51.20160912git.el8.x86_64 1/1
Verifying : net-tools-2.0-0.51.20160912git.el8.x86_64 1/1
Installed:
net-tools-2.0-0.51.20160912git.el8.x86_64
Complete!
Removing intermediate container 3fdcf50a41b2
---> 654c150a48f3
Step 6/7 : EXPOSE 80
---> Running in 7b15e7a16d5d
Removing intermediate container 7b15e7a16d5d
---> 86ff656eb4cb
Step 7/7 : CMD /bin/bash
---> Running in 89d9605dcbec
Removing intermediate container 89d9605dcbec
---> 57bd622f6cb2
Successfully built 57bd622f6cb2
Successfully tagged szc_centos:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
構建完成,然後運行此鏡像的一個容器
$ docker run -it szc_centos
[root@32a8169c4044 tmp]#
會發現默認路徑就是我們在dockerfile裏指定的工作目錄/tmp,並且ifconfig、vim命令是可用的
[root@32a8169c4044 tmp]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)
RX packets 14 bytes 1116 (1.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@32a8169c4044 tmp]# vim test.txt
[root@32a8169c4044 tmp]#
我們也可以查看這個鏡像的歷史
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
szc_centos latest 57bd622f6cb2 5 minutes ago 327MB
...
$ docker history 57bd622f6cb2
IMAGE CREATED CREATED BY SIZE COMMENT
57bd622f6cb2 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
86ff656eb4cb 6 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
654c150a48f3 6 minutes ago /bin/sh -c yum -y install net-tools 26.5MB
e7e3f6dfc31b 6 minutes ago /bin/sh -c yum -y install vim 63.2MB
c014d4c29e27 6 minutes ago /bin/sh -c #(nop) WORKDIR /tmp 0B
8157d08e287e 6 minutes ago /bin/sh -c #(nop) ENV mypath=/tmp 0B
470671670cac 7 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 7 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:aa54047c80ba30064… 237MB
CMD與ENDTRYPOINT
CMD:dockerfile中可以有多個CMD指令,但只有最後一個生效,並且CMD會被docker run之後的參數替換
$ docker run -it -p 7777:8080 tomcat ls -l
total 156
-rw-r--r-- 1 root root 19318 Feb 5 22:30 BUILDING.txt
-rw-r--r-- 1 root root 5408 Feb 5 22:30 CONTRIBUTING.md
-rw-r--r-- 1 root root 57011 Feb 5 22:30 LICENSE
-rw-r--r-- 1 root root 1726 Feb 5 22:30 NOTICE
-rw-r--r-- 1 root root 3255 Feb 5 22:30 README.md
-rw-r--r-- 1 root root 7136 Feb 5 22:30 RELEASE-NOTES
-rw-r--r-- 1 root root 16262 Feb 5 22:30 RUNNING.txt
drwxr-xr-x 2 root root 4096 Feb 27 07:56 bin
drwxr-xr-x 2 root root 4096 Feb 5 22:30 conf
drwxr-xr-x 2 root root 4096 Feb 27 07:56 include
drwxr-xr-x 2 root root 4096 Feb 27 07:56 lib
drwxrwxrwx 2 root root 4096 Feb 5 22:26 logs
drwxr-xr-x 3 root root 4096 Feb 27 07:56 native-jni-lib
drwxrwxrwx 2 root root 4096 Feb 27 07:56 temp
drwxr-xr-x 2 root root 4096 Feb 27 07:56 webapps
drwxr-xr-x 7 root root 4096 Feb 5 22:28 webapps.dist
drwxrwxrwx 2 root root 4096 Feb 5 22:26 work
所以上面的命令根本沒有啓動tomcat,只是列出了tomcat根目錄下的文件
ENTRYPOINT:docker run之後的參數會被傳遞給ENTRYPOINT指令,形成新的指令組合
例如,以下是用ENTRYPOINT訪問http://ip.cn的dockerfile
FROM centos
RUN yum install -y curl
ENTRYPOINT ["curl", "-s", "http://ip.cn"]
而後編譯
$ docker build -f myip_docker -t myip .
Sending build context to Docker daemon 6.144kB
Step 1/3 : FROM centos
---> 470671670cac
Step 2/3 : RUN yum install -y curl
---> Running in 1b3f6d832cfc
CentOS-8 - AppStream 807 kB/s | 6.5 MB 00:08
CentOS-8 - Base 161 kB/s | 5.0 MB 00:31
CentOS-8 - Extras 734 B/s | 2.1 kB 00:02
Last metadata expiration check: 0:00:01 ago on Sun Mar 8 09:00:19 2020.
Package curl-7.61.1-11.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
Removing intermediate container 1b3f6d832cfc
---> e1fe1b0a21a5
Step 3/3 : ENTRYPOINT ["curl", "-s", "http://ip.cn"]
---> Running in b6dbd548d2f0
Removing intermediate container b6dbd548d2f0
---> d144c16678cd
Successfully built d144c16678cd
Successfully tagged myip:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
運行myip容器時可以加上新的選項,來傳給dockerfile裏的curl命令
$ docker run -it myip -i
HTTP/1.1 403 Forbidden
Date: Sun, 08 Mar 2020 09:01:12 GMT
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: __cfduid=d1143a1df005fa16e02870ec8c10c51811583658072; expires=Tue, 07-Apr-20 09:01:12 GMT; path=/; domain=.ip.cn; HttpOnly; SameSite=Lax; Secure
Cache-Control: max-age=15
Expires: Sun, 08 Mar 2020 09:01:27 GMT
Alt-Svc: h3-27=":443"; ma=86400, h3-25=":443"; ma=86400, h3-24=":443"; ma=86400, h3-23=":443"; ma=86400
Server: cloudflare
CF-RAY: 570b5ec859dfd93a-HKG
error code: 1020
ONBUILD案例
ONBUILD關鍵字用來指定當此dockerfile被引用時執行的命令。
以下是案例:先構建myip_docker
FROM centos
RUN yum install -y curl
ENTRYPOINT ["curl", "-s", "https://www.uestc.edu.cn/"]
ONBUILD RUN echo "Father image onbuild finished.."
然後構建鏡像
$ docker build -f myip_docker -t myip .
再編寫mydocker_son,引用鏡像myip
FROM myip
RUN yum install -y curl
CMD ["curl", "-s", "http://www.baidu.com"]
使用此文件構建鏡像時,myip的dockerfile中的ONBUILD語句就會執行
$ docker build -f myip_son -t myip_son .
...
Father image onbuild finished..
...
Successfully built 770b567e828f
Successfully tagged myip_son:latest
...
自定義tomcat
dockerfile內容如下,編譯此文件需要其所在目錄下有c.txt、jdk-8u171-linux-x64.tar.gz和apache-tomcat-9.0.8.tar.gz三個文件
FROM centos
MAINTAINER songzeceng
COPY c.txt /usr/local/c_s.txt # 把文件複製到鏡像指定文件中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/ # 把壓縮包解壓後複製到鏡像指定目錄中
ADD apache-tomcat-9.0.8.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD $CATALINA_HOME/bin/startup.sh && tail -F $CATALINA_HOME/bin/logs/logs.txt # 輸出日誌
而後編譯
$ docker build -f my_tomcat_docker -t szc_tomcat .
最後運行
$ docker run -d -p 9080:8080 --name szc_tomcat_00 -v /c/Users/songzeceng/tomcat/out:/usr/local/apache-tomcat-9.0.8/webapps/test -v /c/Users/songzeceng.tomcat/logs:/usr/local/apache-tomcat-9.0.8/logs --privileged=true szc_tomcat
-d表示後臺運行容器,然後指定端口映射、容器名字,以及兩個數據卷,最後--privileged=true確保容器可寫