Dockerfile - 工作流程、构建镜像、文件语法

目录

一、Dockerfile

1.1、简介

[1.2、Dockerfile 构建镜像的流程](#1.2、Dockerfile 构建镜像的流程)

[1.3、Dockerfile 文件语法](#1.3、Dockerfile 文件语法)

1.3.1、注意事项

1.3.2、FROM

1.3.3、MAINTAINER(官方已废弃)

1.3.4、RUN

1.3.5、EXPOSE

1.3.6、WORKDIR

[1.3.7、ADD 和 COPY](#1.3.7、ADD 和 COPY)

1.3.8、ENV

1.3.9、VOLUME

[1.3.10、CMD 和 ENTRYPOINT](#1.3.10、CMD 和 ENTRYPOINT)


一、Dockerfile


1.1、简介

a)Dockerfile 是什么?

Dockerfile 就是镜像的描述文件.

b)Dockerfile 的作用?

通过 Dockerfile 文件就可以构建一个属于自己的镜像.

c)为什么使用 Dockerfile 构建镜像?

官方的镜像确实足够好了,适用于大多数应用场景,但是如果我们想要构建属于我们自己的业务镜像,就需要自定义镜像了.

例如,你写了一个 Spring 项目,还用到了,redis,tomcat...... 这些容器,那么你部署项目的时候,还需要先去启动 redis,tomcat ...... 这些容器,并且如果要部署到多台机器上,整个部署的过程就相当繁琐. 通过 Dockerfile 就可以提前将这些部署操作写好,我们只需要通过 build 指令构建镜像,最后运行镜像就完成了部署.

d)如何通过 Dockerfile 构建镜像?

a. 在指定位置创建一个 Dockerfile 文件,进行编写.

b. 通过以下命令构建镜像.

docker build -t 自定义镜像名:自定义版本 .(指定 Dockerfile 文件所在位置,"." 表示当前目录)

1.2、Dockerfile 构建镜像的流程

a)编写 Dockerfile 文件:例如在 /root 目录下创建一个 Dockerfile 文件进行编写,就称 /root(Dockerfile 文件所在目录)为 context(上下文).

b)请求 DockerServer 构建:因为 Docker 也是一个客户端服务器程序,因此我们可以在客户端通过 build 命令来请求 DockerServer 进行构建镜像.

c)开始构建:DockerServer 会拿到 context(上下文)中的所有 Dockerfile 开始构建. 具体的,会对 Dockerfile 文件中的每一行指令都构建出一个 临时镜像,并保存到 cache 中(这样做是为了日后如果有修改 Dockerfile 文件,比如在原来的基础上增加了几条命令,那么之前命令构建好的镜像就直接从缓存里拿了,提升了构建速度),最后就构建出了一个最终的镜像.

Ps:Dockerfile 编写要求,一行只能存在一条完成的命令

d)特例1:如果 context 中存在 dockerIgnore 文件,那么本次构建则不会构建 dockerIgnore 文件中描述的文件.

e)特里2:如果我就想让 DockerServer 每次都把 Dockerfile 中的命令都加载一遍,就可以在 build 命令中加上 --no-cache 参数,这样就不会把每次生成的零时镜像保存到 cache 中.

1.3、Dockerfile 文件语法

1.3.1、注意事项

  1. 每条指令都必须大写,后面都至少需要一个参数.
  2. 指令按照从上到下,顺序执行.
  3. 表示注释.

  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交(临时镜像).

1.3.2、FROM

a)表示当前镜像是基于哪一个镜像的.

这个指令是非常有必要的,因为一个容器就是一个操作系统,我们写的 Dockerfile 总不可能每次都是从操作系统的层面写起. 例如你的运行的是一个 Java 项目,那么就需要 JDK 环境来支撑,总不能自己手写 JDK 吧~

FROM 基于哪个镜像

Ps:第一个指令必须是 FROM

b)例如,我们要构建一个镜像,是基于 centos 镜像的,那么就需要创建一个 Dockerfile 文件,编写内容如下

FROM centos:7

通过如下指令通过当前目录下的 Dockerfile 文件构建名为 mycentos 镜像

[root@VM-8-17-centos dockerfile]# docker build -t mycentos:1 .
[+] Building 0.1s (5/5) FINISHED                                                                                                                            docker:default
 => [internal] load build definition from Dockerfile                                                                                                                  0.0s
 => => transferring dockerfile: 56B                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                                       0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                                                      0.0s
 => [1/1] FROM docker.io/library/centos:latest                                                                                                                        0.0s
 => exporting to image                                                                                                                                                0.0s
 => => exporting layers                                                                                                                                               0.0s
 => => writing image sha256:22773018c04267669821153cd42ef21101902b10a8a16f340fbef85a77821d03                                                                          0.0s
 => => naming to docker.io/library/mycentos:1                                                                                                                         0.0s

这样,我们自己的镜像就构建好了

[root@VM-8-17-centos dockerfile]# docker images
REPOSITORY                  TAG              IMAGE ID       CREATED       SIZE
centos                      latest           5d0da3dc9764   2 years ago   231MB
mycentos                    1                22773018c042   2 years ago   231MB

1.3.3、MAINTAINER(官方已废弃)

镜像维护者的姓名和邮箱地址.

Ps:官方已废弃,这里就不讲了

1.3.4、RUN

a)构建镜像时需要运行的指令.

RUN 要运行的指令

b)例如要基于 centos 构建镜像,同时希望下载好 vim 编辑器,RUN 指令的写法就有以下两种方式

# 第一种写法
RUN yum install -y vim
# 第二种写法
RUN ["yum", "install", "-y", "vim"]

这里使用第一种方式来演示,那么 Dockerfile 文件如下

FROM centos:7
RUN yum install -y vim

构建镜像

[root@VM-8-17-centos dockerfile]# docker build -t mycentos:1 .
[+] Building 35.6s (6/6) FINISHED                                                                                                                           docker:default
 => [internal] load .dockerignore                                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                                       0.0s
 => [internal] load build definition from Dockerfile                                                                                                                  0.0s
 => => transferring dockerfile: 74B                                                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                                                           0.0s
 => CACHED [1/2] FROM docker.io/library/centos:7                                                                                                                      0.0s
 => [2/2] RUN yum install -y vim                                                                                                                                     33.7s
 => exporting to image                                                                                                                                                1.9s 
 => => exporting layers                                                                                                                                               1.8s 
 => => writing image sha256:e30f98790cacacea34fce01e42b64b14dd5e489645e4df6f1b4f9e3ac31c12b6                                                                          0.0s 
 => => naming to docker.io/library/mycentos:1                                                                                                                         0.0s 

运行容器,检查 vim 是否安装成功

[root@VM-8-17-centos dockerfile]# docker run -it mycentos:1
[root@795b36479fe7 /]# ll
total 64
-rw-r--r--   1 root root 12114 Nov 13  2020 anaconda-post.log
lrwxrwxrwx   1 root root     7 Nov 13  2020 bin -> usr/bin
drwxr-xr-x   5 root root   360 Dec 28 02:57 dev
drwxr-xr-x   1 root root  4096 Dec 28 02:57 etc
drwxr-xr-x   2 root root  4096 Apr 11  2018 home
lrwxrwxrwx   1 root root     7 Nov 13  2020 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Nov 13  2020 lib64 -> usr/lib64
drwxr-xr-x   2 root root  4096 Apr 11  2018 media
drwxr-xr-x   2 root root  4096 Apr 11  2018 mnt
drwxr-xr-x   2 root root  4096 Apr 11  2018 opt
dr-xr-xr-x 115 root root     0 Dec 28 02:57 proc
dr-xr-x---   2 root root  4096 Nov 13  2020 root
drwxr-xr-x   1 root root  4096 Dec 28 02:56 run
lrwxrwxrwx   1 root root     8 Nov 13  2020 sbin -> usr/sbin
drwxr-xr-x   2 root root  4096 Apr 11  2018 srv
dr-xr-xr-x  13 root root     0 Dec 28 02:57 sys
drwxrwxrwt   1 root root  4096 Dec 28 02:56 tmp
drwxr-xr-x   1 root root  4096 Nov 13  2020 usr
drwxr-xr-x   1 root root  4096 Nov 13  2020 var
[root@795b36479fe7 /]# vim test   
[root@795b36479fe7 /]# cat test
hellow world

Ps:-it 参数表示运行容器后立即与容器进行交互,如果不加此参数,运行 centos 容器启动后会立即结束(centos 镜像中没有需要执行的任务)

1.3.5、EXPOSE

a)声明当前容器对外暴露的端口号. 此命令的作用只是声明,日后方便别人看的,因为端口号暴露是可以在 docker run 启动容器时通过 -p 参数指定的.

EXPOSE 端口号

b)例如,声明该容器暴露的端口号为 8080、15672、5672,那么 Dockerfile 文件编写如下

FROM centos:7
RUN yum install -y vim
# 这里只是声明容器中使用的端口号
EXPOSE 8080
EXPOSE 15672
EXPOSE 5672

1.3.6、WORKDIR

a)指定在创建容器后,终端默认进来的工作目录(一个落脚点). 如果 WORKDIR 指定的目录不存在,就会自动创建目录结构并进入.

# 绝对路径
WORKDIR /apps/data
# 相对路径
WORKDIR a

# 注意:WORKDIR 指令可以在 Dockerfile 文件中多次使用.  以上连续使用就表示,
# 先进入 /apps/data 目录,然后在进入 /apps/data/a 目录

b)例如,先进入 /apps/data 目录,在进入 /apps/data/a 目录,那么 Dockerfile 文件如下

FROM centos:7
RUN yum install -y vim
# 这里只是声明容器中使用的端口号
EXPOSE 8080
EXPOSE 15672
EXPOSE 5672
WORKDIR /apps/data
WORKDIR a

构建好后进入镜像,检查当前所在目录

[root@VM-8-17-centos dockerfile]# docker build -t mycentos3 .
[+] Building 0.3s (8/8) FINISHED                                                                                                                            docker:default
 => [internal] load build definition from Dockerfile                                                                                                                  0.0s
 => => transferring dockerfile: 191B                                                                                                                                  0.0s
 => [internal] load .dockerignore                                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                                       0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                                                           0.0s
 => [1/4] FROM docker.io/library/centos:7                                                                                                                             0.0s
 => CACHED [2/4] RUN yum install -y vim                                                                                                                               0.0s
 => [3/4] WORKDIR /apps/data                                                                                                                                          0.1s
 => [4/4] WORKDIR a                                                                                                                                                   0.1s
 => exporting to image                                                                                                                                                0.1s
 => => exporting layers                                                                                                                                               0.1s
 => => writing image sha256:5661a00d5fe4468bb0f231d44e5c16e609d65f3e37ac8c24697c8a6e8220eab9                                                                          0.0s
 => => naming to docker.io/library/mycentos3                                                                                                                          0.0s
[root@VM-8-17-centos dockerfile]# 
[root@VM-8-17-centos dockerfile]# docker run -it mycentos3
[root@89c6748a1083 a]# pwd
/apps/data/a
[root@89c6748a1083 a]# 

1.3.7、ADD 和 COPY

a)将宿主机目录下的文件拷贝到镜像.

ADD 宿主机目录或URL 容器内目录
COPY 构建上下文中的文件 容器内目录

b)ADD 和 COPY的区别:

相同点:

  1. ADD 和 COPY 都是用来拷贝宿主机上的文件到镜像中.

不同点:

  1. ADD 如果拷贝的是一个 tar 包,会自动解压.
  2. COPY 只能拷贝上下文中的文件到工作目录,ADD 可以将宿主机上任意目录下的文件拷贝到镜像.
  3. ADD 不仅可以拷贝宿主机文件,还可以通过指定 URL 来下载需要的文件.

c)例如,将当前目录下的 aa.txt 文件拷贝到容器的工作目录,Dockerfile 文件如下

FROM centos:7
RUN yum install -y vim
# 这里只是声明容器中使用的端口号
EXPOSE 8080
EXPOSE 15672
EXPOSE 5672
WORKDIR /apps/data
WORKDIR a
ADD aa.txt .

构建镜像后进入容器,检查文件

[root@VM-8-17-centos dockerfile]# docker build -t mycentos:1 .
[+] Building 0.2s (10/10) FINISHED                                                                                                                          docker:default
 => [internal] load build definition from Dockerfile                                                                                                                  0.0s
 => => transferring dockerfile: 204B                                                                                                                                  0.0s
 => [internal] load .dockerignore                                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                                       0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                                                           0.0s
 => [1/5] FROM docker.io/library/centos:7                                                                                                                             0.0s
 => [internal] load build context                                                                                                                                     0.0s
 => => transferring context: 45B                                                                                                                                      0.0s
 => CACHED [2/5] RUN yum install -y vim                                                                                                                               0.0s
 => CACHED [3/5] WORKDIR /apps/data                                                                                                                                   0.0s
 => CACHED [4/5] WORKDIR a                                                                                                                                            0.0s
 => [5/5] ADD aa.txt .                                                                                                                                                0.1s
 => exporting to image                                                                                                                                                0.0s
 => => exporting layers                                                                                                                                               0.0s
 => => writing image sha256:66e032475f19cd2dec85f8007cc5329b68eae84b876d5b0b180d588059d86c45                                                                          0.0s
 => => naming to docker.io/library/mycentos:1                                                                                                                         0.0s
[root@VM-8-17-centos dockerfile]# 
[root@VM-8-17-centos dockerfile]# docker run -it mycentos:1
[root@cac57774ec9d a]# ls
aa.txt
[root@cac57774ec9d a]# cat aa.txt
hello world
[root@cac57774ec9d a]# pwd
/apps/data/a

1.3.8、ENV

a)用来在构建镜像过程中设置环境变量.

# 创建环境变量如下
ENV 自定义变量名=值

# 使用:通过 $自定义变量名 即可使用

b)例如,自定义变量名为 BASE_PATH,值为 /apps/data ,用来给 WORKDIR 进行配置.

FROM centos:7
RUN yum install -y vim
# 这里只是声明容器中使用的端口号
EXPOSE 8080
EXPOSE 15672
EXPOSE 5672
# 配置环境变量
ENV BASE_PATH=/apps/data
WORKDIR $BASE_PATH
ADD aa.txt .

构建后进入容器,检查当前目录

[root@VM-8-17-centos dockerfile]# docker build -t mycentos:2 .
[+] Building 0.2s (9/9) FINISHED                                                                                                                            docker:default
 => [internal] load .dockerignore                                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                                       0.0s
 => [internal] load build definition from Dockerfile                                                                                                                  0.0s
 => => transferring dockerfile: 239B                                                                                                                                  0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                                                           0.0s
 => [1/4] FROM docker.io/library/centos:7                                                                                                                             0.0s
 => [internal] load build context                                                                                                                                     0.0s
 => => transferring context: 27B                                                                                                                                      0.0s
 => CACHED [2/4] RUN yum install -y vim                                                                                                                               0.0s
 => CACHED [3/4] WORKDIR /apps/data                                                                                                                                   0.0s
 => [4/4] ADD aa.txt .                                                                                                                                                0.0s
 => exporting to image                                                                                                                                                0.0s
 => => exporting layers                                                                                                                                               0.0s
 => => writing image sha256:1ef398b6982b0ce29fb20c7aa1383150694791b3d898c1b6d19c12fdea994517                                                                          0.0s
 => => naming to docker.io/library/mycentos:2                                                                                                                         0.0s
[root@VM-8-17-centos dockerfile]# docker run -it mycentos:2
[root@500be777bf0a data]# pwd
/apps/data

1.3.9、VOLUME

a)容器数据卷,用来声明容器中的某个目录可以挂载到宿主机中. 这个命令和 EXPOSE 一样也仅仅只是声明,因为将来通过 docker run 启动容器时可以通过 -v 参数指定数据卷挂载.

VOLUME 目录

b)例如,声明容器中的 /apps/data 目录可以挂载到宿主机中,如下

VOLUME /apps/data

1.3.10、CMD 和 ENTRYPOINT

a)CMD & ENTRYPOINT 的作用

都是用来指定容器启动时默认执行的指令.

Ps:CMD 指令可以存在多个,但是存在多个只有最后一个生效.

b)使用语法

CMD 命令
ENTRYPOINT 命令

例如命令是 java -jar demo.jar ,这里实际上有两种方式书写:

  • 直接命令方式:java -jar demo.jar
  • 字符串数组方式(推荐):["java", "-jar", "demo.jar"]

推荐原因:通过字符串数组的方式,在未来启动容器的时候,如果需要调整,可以覆盖数组中的参数(怎么覆盖,下文会讲)

c)区别

覆盖参数的方式不一样,例如启动 centos 命令原本要初始化的命令为 ls /apps/data,现在要覆盖成 ls /

  1. cmd 配置后,启动容器时进行覆盖如下:

    语法

    docker run 镜像:版本号 覆盖自己定义的命令

    当前场景的写法

    docker run centos:7 ls /

  2. entrypoint 配置后,启动容器时进行覆盖如下:

    语法

    docker run --entrypoint=覆盖指令 镜像:版本号 传递参数

    当前场景写法

    docker run --entrypoint=ls centos:7 /

Ps:使用的前提必须是字符串数组的方式

d)如何使用

从上述区别中也可以看出,entrypoint 的覆盖方式比较麻烦,因此一个较为普遍的使用方式:

  • entrypoint 用来书写一个容器固定的指令.
  • cmd 用来给 entrypoint 传递参数.

例如,需要初始化的命令为 ls /apps/data ,那么 Dockerfile 文件如下

FROM centos:7
RUN yum install -y vim
# 这里只是声明容器中使用的端口号
EXPOSE 8080
EXPOSE 15672
EXPOSE 5672
# 命令 ls ,参数 /apps/data
ENTRYPOINT ["ls"]
CMD ["/apps/data"]

构建镜像并启动容器

[root@VM-8-17-centos dockerfile]# docker build -t mycentos:2 .
[+] Building 0.1s (9/9) FINISHED                                                                                                                            docker:default
 => [internal] load build definition from Dockerfile                                                                                                                  0.0s
 => => transferring dockerfile: 263B                                                                                                                                  0.0s
 => [internal] load .dockerignore                                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                                       0.0s
 => [internal] load metadata for docker.io/library/centos:7                                                                                                           0.0s
 => [1/4] FROM docker.io/library/centos:7                                                                                                                             0.0s
 => [internal] load build context                                                                                                                                     0.0s
 => => transferring context: 27B                                                                                                                                      0.0s
 => CACHED [2/4] RUN yum install -y vim                                                                                                                               0.0s
 => CACHED [3/4] WORKDIR /apps/data                                                                                                                                   0.0s
 => CACHED [4/4] ADD aa.txt .                                                                                                                                         0.0s
 => exporting to image                                                                                                                                                0.0s
 => => exporting layers                                                                                                                                               0.0s
 => => writing image sha256:148a9754a1fd4bff7e6c15a70db21cf594a7811378420057996207dc1ec0ffd1                                                                          0.0s
 => => naming to docker.io/library/mycentos:2                                                                                                                         0.0s
[root@VM-8-17-centos dockerfile]# 
[root@VM-8-17-centos dockerfile]# 
[root@VM-8-17-centos dockerfile]# docker run mycentos:2
aa.txt
[root@VM-8-17-centos dockerfile]# 
[root@VM-8-17-centos dockerfile]# docker run mycentos:2 /
anaconda-post.log
apps
bin
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var

这样将来一旦要修改初始化参数,就可以直接在启动容器时进行修改.

相关推荐
C++忠实粉丝20 分钟前
Linux环境基础开发工具使用(2)
linux·运维·服务器
康熙38bdc43 分钟前
Linux 环境变量
linux·运维·服务器
存储服务专家StorageExpert1 小时前
DELL SC compellent存储的四种访问方式
运维·服务器·存储维护·emc存储
hakesashou2 小时前
python如何比较字符串
linux·开发语言·python
Ljubim.te2 小时前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
cooldream20092 小时前
Linux性能调优技巧
linux
大G哥2 小时前
记一次K8S 环境应用nginx stable-alpine 解析内部域名失败排查思路
运维·nginx·云原生·容器·kubernetes
长天一色2 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
醉颜凉2 小时前
银河麒麟桌面操作系统修改默认Shell为Bash
运维·服务器·开发语言·bash·kylin·国产化·银河麒麟操作系统
QMCY_jason3 小时前
Ubuntu 安装RUST
linux·ubuntu·rust