Docker系列07—Dockerfile 详解

本文收录在容器技术学习系列文章总目录 1、认识Dockerfile 1.1 镜像的生成途径 基于容器制作 dockerfile,docker build   基于容器制作镜像,已经在上篇详细讲解过了;这篇主要讲解基于Dockerfile,使用docker build 命令制作镜像。 1.2 Dockerfile 介绍   Docker中有个非常重要的概念叫做——镜像(Image)。Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。   镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的问题、体积的问题就都会解决。这个脚本就是 Dockerfile。   Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。 1.3 Dockerfile 指令 FROM MAINTAINER COPY ADD WORKDIR VOLUME EXPOSE ENV RUN CMD ENTRYPOINT HEALTHCHECK ONBUILD USER ARG SHELL STOPSIGNAL 1.4 Dockerfile 的使用 (1)Dockerfile 编写的基本结构 Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释。 (2)一台主机可以有多个Dockerfile   要使用多个Dockerfile 创建镜像,可以在不同目录编写Dockerfile,然后在Dockerfile 所在的目录下构建新的镜像;   注意:Dockerfile 中所包含的需要的内容;如COPY的文件、目录等,都需要在Dockerfile 同级目录下存在; (3)docker build 基于dockerfile制作镜像的命令 ① 格式: 1 docker build [OPTIONS] PATH | URL | - ② 选项: -t:打标签 -c,- cpu-shares int :CPU份额(相对权重) -m,- memory bytes:内存限制 --build-arg:设置构建时变量,就是构建的时候修改ARG指令的参数 2、FROM 指令 2.1 介绍 FROM 指令必须是 Dockerfile 中非注释行的第一个指令,即一个 Dockerfile 从FROM语句; FROM 指令用于为镜像文件构建过程指定基础镜像,后续的指令运行于此基础镜像所提供的运行环境; 实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会自动从 Docker 的公共库 pull 镜像下来。如果找不到指定的镜像文件,docker build 会返回一个错误信息; FROM可以在一个 Dockerfile 中出现多次,如果有需求在一个 Dockerfile 中创建多个镜像。 如果FROM语句没有指定镜像标签,则默认使用latest标签。 2.2 格式 1 2 FROM [:] 或 FROM @ 注: :指定作为base image的名称; :base image的标签,省略时默认latest; :是镜像的哈希码;使用哈希码会更安全一点; 2.3 示例 1 2 # Description: test image FROM busybox:latest 3、MAINTAINER 3.1 介绍 用于让dockerfile制作者提供本人的详细信息 dockerfile 并不限制MAINTAINER 指令可在出现的位置,但推荐将其放置于FROM指令之后 3.2 格式 1 MAINTAINER 3.3 示例 1 2 3 # Description: test image FROM busybox:latest MAINTAINER "Along " 4、COPY 4.1 介绍 用于从docker 主机复制新文件或者目录至创建的新镜像指定路径中 4.2 格式 1 2 COPY ... 或 COPY ["",... ""] 注: :要复制的源文件或目录,支持使用通配符; :目标路径,即正在创建的image的文件系统路径;建议使用绝对路径,否则,COPY指定以WORKDIR为其实路径 在路径中有空白字符时,通常使用第2中格式; 4.3 文件复制准则 必须是build上下文中的路径,不能是其父目录中的文件; 如果是目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制; 如果指定了多个,或在中使用了通配符,则必须是一个目录,且必须以 / 结尾; 如果事先不存在,他将会被自动创建,这包括父目录路径。 4.4 示例 4.4.1 COPY 文件 (1)编写dockerfile文件 1 2 3 4 # Description: test image FROM busybox:latest MAINTAINER "Along " COPY index.html /data/web/html/ #要确保dockerfile 同级路径下有index.html文件 (2)在dockerfile同级目录下准备好index.html文件 1 2 $ vim index.html

Busybox httpd server

(3)使用build 制作镜像 1 2 3 4 5 6 7 8 9 10 11 12 $ docker build -t busyboxhttpd:v0.1 ./ Sending build context to Docker daemon 3.072 kB Step 1/3 : FROM busybox:latest ---> 758ec7f3a1ee Step 2/3 : MAINTAINER "Along " ---> Running in 0d6f4c1c0e8d ---> 5d2cda1631d7 Removing intermediate container 0d6f4c1c0e8d Step 3/3 : COPY index.html /data/web/html/ ---> 2e0fe0eb0cb7 Removing intermediate container 536fdc71472a Successfully built 2e0fe0eb0cb7    (4)基于此新建镜像运行容器,进行验证 1 2 [root@along ~]# docker run --name web1 --rm busyboxhttpd:v0.1 cat /data/web/html/index.html

Busybox httpd server

  注:--rm:在容器关闭时,直接删除容器,方便实验。 4.4.2 COPY 目录 (1)编写dockerfile文件 1 2 3 4 5 # Description: test image FROM busybox:latest MAINTAINER "Along " COPY index.html /data/web/html/ COPY yum.repos.d /etc/yum.repos.d/ 注:如果是复制目录,则其内部文件或子目录会被递归复制,但目录自身不会被复制;需要把复制目录名字也写在容器中要复制的路径下! (2)在dockerfile同级目录下准备好yum.repos.d 目录 1 2 3 [root@along img1]# cp -r /etc/yum.repos.d/ ./ [root@along img1]# ls yum.repos.d along.repo docker-ce.repo epel-release-latest-7.noarch.rpm epel.repo epel-testing.repo    (3)使用build 制作镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@along img1]# docker build -t busyboxhttpd:v0.2 ./ Sending build context to Docker daemon 27.65 kB Step 1/4 : FROM busybox:latest ---> 758ec7f3a1ee Step 2/4 : MAINTAINER "Along " ---> Using cache ---> 5d2cda1631d7 Step 3/4 : COPY index.html /data/web/html/ ---> Using cache ---> 2e0fe0eb0cb7 Step 4/4 : COPY yum.repos.d /etc/yum.repos.d/ ---> 68586925bdf9 Removing intermediate container a01f824efa3e Successfully built 68586925bdf9    (4)基于此新建镜像运行容器,进行验证 1 2 3 4 5 6 [root@along ~]# docker run --name web1 --rm busyboxhttpd:v0.2 ls /etc/yum.repos.d/ along.repo docker-ce.repo epel-release-latest-7.noarch.rpm epel-testing.repo epel.repo    5、ADD 5.1 介绍 ADD 指令类似于COPY指令,ADD支持使用TAR文件和URL路径 5.2 格式 1 2 ADD .. 或 ADD ["".. ""] 5.3 操作准则 同COPY指令 如果为URL且不以 / 结尾,则指定的文件将被下载并直接被创建为;如果以/结尾,则文件名URL指定的文件将被直接下载并保存为/ 如果是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于"tar-x"命令;然而,通过URL获取到的tar文件将不会自动展开; 如果有多个,或其间接或直接使用了通配符,则必须是一个以/结尾的目录路径 ;如果不以/结尾,则其被视作一个普通文件,的内容将被直接写入到; 5.4 示例 5.4.1 COPY 网上路径(URL)的tar包 (1)编写dockerfile文件 1 2 3 4 5 6 # Description: test image FROM busybox:latest MAINTAINER "Along " COPY index.html /data/web/html/ COPY yum.repos.d /etc/yum.repos.d/ ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/ 注:ADD 的 是网上的nginx下载路径 (2)使用build 制作镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [root@along img1]# docker build -t busyboxhttpd:v0.3 ./ Sending build context to Docker daemon 27.65 kB Step 1/5 : FROM busybox:latest ---> 758ec7f3a1ee Step 2/5 : MAINTAINER "Along " ---> Using cache ---> 5d2cda1631d7 Step 3/5 : COPY index.html /data/web/html/ ---> Using cache ---> 2e0fe0eb0cb7 Step 4/5 : COPY yum.repos.d /etc/yum.repos.d/ ---> Using cache ---> 68586925bdf9 Step 5/5 : ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/ Downloading 1.028 MB/1.028 MB ---> 91c71b469a9e Removing intermediate container abbad8dcdefb Successfully built 91c71b469a9e    (3)基于此新建镜像运行容器,进行验证 1 2 [root@along ~]# docker run --name web1 --rm busyboxhttpd:v0.3 ls /usr/local/src nginx-1.15.8.tar.gz    5.4.2 COPY 本地的路径的tar包 (1)编写dockerfile文件 1 2 3 4 5 6 7 # Description: test image FROM busybox:latest MAINTAINER "Along " COPY index.html /data/web/html/ COPY yum.repos.d /etc/yum.repos.d/ #ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/ ADD nginx-1.15.8.tar.gz /usr/local/src/    (2)在dockerfile同级目录下准备好yum.repos.d 目录 1 [root@along img1]# wget http://nginx.org/download/nginx-1.15.8.tar.gz    (3)使用build 制作镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@along img1]# docker build -t busyboxhttpd:v0.4 ./ Sending build context to Docker daemon 1.056 MB Step 1/5 : FROM busybox:latest ---> 758ec7f3a1ee Step 2/5 : MAINTAINER "Along " ---> Using cache ---> 5d2cda1631d7 Step 3/5 : COPY index.html /data/web/html/ ---> Using cache ---> 2e0fe0eb0cb7 Step 4/5 : COPY yum.repos.d /etc/yum.repos.d/ ---> Using cache ---> 68586925bdf9 Step 5/5 : ADD nginx-1.15.8.tar.gz /usr/local/src/ ---> f99baec4b992 Removing intermediate container 7f02f3fe649e    (4)基于此新建镜像运行容器,进行验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 [root@along ~]# docker run --name web1 --rm busyboxhttpd:v0.4 ls /usr/local/src /usr/local/src/nginx-1.15.8 /usr/local/src: nginx-1.15.8 /usr/local/src/nginx-1.15.8: CHANGES CHANGES.ru LICENSE README auto conf configure contrib html man src    6、WORKDIR 6.1 介绍 用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录 6.2 格式 1 WORKDIR   在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相对路径,不过,其是相对此前一个WORKDIR指令指定的路径;   另外,WORKDIR也可调用由ENV指定定义的变量; 6.3 示例 1 2 3 4 5 6 7 # Description: test image FROM busybox:latest MAINTAINER "Along " COPY index.html /data/web/html/ COPY yum.repos.d /etc/yum.repos.d/ WORKDIR /usr/local/ ADD nginx-1.15.8.tar.gz ./src/    7、VOLUME 7.1 介绍 用于在image中创建一个挂载点目录,以挂载Docker host.上的卷或其它容器上的卷 7.2 语法 1 2 VOLUME 或 VOLUME [""] 注:如果挂载点目录路径下此前在文件存在,docker run命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中 7.3 示例 (1)编写dockerfile文件 1 2 3 4 5 6 7 8 9 10 11 12 # Description: test image FROM busybox:latest MAINTAINER "Along " COPY index.html /data/web/html/ COPY yum.repos.d /etc/yum.repos.d/ #ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/ WORKDIR /usr/local/ ADD nginx-1.15.8.tar.gz ./src/ VOLUME /data/mysql    (2)使用build 制作镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 [root@along img1]# docker build -t busyboxhttpd:v0.5 ./ Sending build context to Docker daemon 1.056 MB Step 1/7 : FROM busybox:latest ---> 758ec7f3a1ee Step 2/7 : MAINTAINER "Along " ---> Using cache ---> 5d2cda1631d7 Step 3/7 : COPY index.html /data/web/html/ ---> Using cache ---> 2e0fe0eb0cb7 Step 4/7 : COPY yum.repos.d /etc/yum.repos.d/ ---> Using cache ---> 68586925bdf9 Step 5/7 : WORKDIR /usr/local/ ---> Using cache ---> 84ad38ba3b4d Step 6/7 : ADD nginx-1.15.8.tar.gz ./src/ ---> Using cache ---> b32e992f51c5 Step 7/7 : VOLUME /data/mysql ---> Running in 270bd9a938eb ---> 90d592698082 Removing intermediate container 270bd9a938eb Successfully built 90d592698082    (3)基于此新建镜像运行容器,进行验证 1 2 3 4 5 [root@along ~]# docker run --name web1 --rm -it busyboxhttpd:v0.5 /bin/sh /usr/local # --- 另打开一个终端,查询存储卷 [root@along ~]# docker inspect -f {{.Mounts}} web1 [{volume b788b8a50d69953e2b086b3b54ba683154647319a481246cb7ab2ff927b21372 /var/lib/docker/volumes/b788b8a50d69953e2b086b3b54ba683154647319a481246cb7ab2ff927b21372/_data /data/mysql local true }]    8、EXPOSE 8.1 介绍 用于为容器打开指定要监听的端口以实现与外部通信 8.2 语法 1 EXPOSE [/ ] [[/ ] .... 注: 用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议 EXPOSE指令可一次指定多个端口,例如:EXPOSE 11211/udp 11211/tcp 8.3 示例 (1)编写dockerfile文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # Description: test image FROM busybox:latest MAINTAINER "Along " COPY index.html /data/web/html/ COPY yum.repos.d /etc/yum.repos.d/ #ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/ WORKDIR /usr/local/ ADD nginx-1.15.8.tar.gz ./src/ VOLUME /data/mysql EXPOSE 80/tcp    (2)使用build 制作镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [root@along img1]# docker build -t busyboxhttpd:v0.6 ./ Sending build context to Docker daemon 1.056 MB Step 1/8 : FROM busybox:latest ---> 758ec7f3a1ee Step 2/8 : MAINTAINER "Along " ---> Using cache ---> 5d2cda1631d7 Step 3/8 : COPY index.html /data/web/html/ ---> Using cache ---> 2e0fe0eb0cb7 Step 4/8 : COPY yum.repos.d /etc/yum.repos.d/ ---> Using cache ---> 68586925bdf9 Step 5/8 : WORKDIR /usr/local/ ---> Using cache ---> 84ad38ba3b4d Step 6/8 : ADD nginx-1.15.8.tar.gz ./src/ ---> Using cache ---> b32e992f51c5 Step 7/8 : VOLUME /data/mysql ---> Using cache ---> 90d592698082 Step 8/8 : EXPOSE 80/tcp ---> Running in 53b13561994d ---> 182463025992 Removing intermediate container 53b13561994d Successfully built 182463025992    (4)基于此新建镜像运行容器,进行验证 1 2 3 4 5 6 7 8 9 10 11 [root@along ~]# docker run --name web1 -P --rm -it busyboxhttpd:v0.6 /bin/httpd -f -h /data/web/html --- 另打开一个终端,验证httpd 服务的80端口 [root@along ~]# docker inspect -f {{.NetworkSettings.IPAddress}} web1 #查询容器的IP 172.17.0.2 [root@along ~]# curl 172.17.0.2:80

Busybox httpd server

--- 在宿主机通过暴露的端口访问httpd 服务 [root@along ~]# docker port web1 80/tcp -> 0.0.0.0:32768 [root@along ~]# curl 127.0.0.1:32768

Busybox httpd server

注:就算dockerfile 中有EXPOSE 指令暴露端口,但是不是真正的暴露;需要在启动容器时,使用-P 选项真正的暴露端口。 9、ENV 9.1 介绍 用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)所调用 调用格式为$variable_ name 或 ${variable_ name} 9.2 格式 1 2 ENV 或 ENV = . . 注: 第一种格式中,之后的所有内容均会被视作其的组成部分, 因此,一次只能设置一个变量; 第二种格式可用一次设置多个变量,每个变量为一个”="的键值对,如果中包含空格,可以以反斜线(\)进行转义,也可通过对加引号进行标识;另外,反斜线也可用于续行; 定义多个变量时,建议使用第二种方式,以便在同一层中完成所有功能 9.3 示例 (1)编写dockerfile文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # Description: test image FROM busybox:latest MAINTAINER "Along " ENV DOC_ROOT=/data/web/html/ \ WEB_SERVER_PACKAGE="nginx-1.15.8" COPY index.html ${DOC_ROOT} COPY yum.repos.d /etc/yum.repos.d/ #ADD http://nginx.org/download/nginx-1.15.8.tar.gz /usr/local/src/ WORKDIR /usr/local/ ADD ${WEB_SERVER_PACKAGE}.tar.gz ./src/ VOLUME /data/mysql EXPOSE 8080:80/tcp    (2)使用build 制作镜像 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Sending build context to Docker daemon 1.056 MB Step 1/9 : FROM busybox:latest ---> 758ec7f3a1ee Step 2/9 : MAINTAINER "Along " ---> Using cache ---> 5d2cda1631d7 Step 3/9 : ENV DOC_ROOT /data/web/html/ WEB_SERVER_PACKAGE "nginx-1.15.8" ---> Running in b268b672236a ---> 295bf19a8395 Removing intermediate container b268b672236a Step 4/9 : COPY index.html ${DOC_ROOT} ---> c29d3c8f6e0d Removing intermediate container 33238b2ba6bf Step 5/9 : COPY yum.repos.d /etc/yum.repos.d/ ---> 3a2a2f571b07 Removing intermediate container bc49392442bc Step 6/9 : WORKDIR /usr/local/ ---
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信