Docker 提供了两种构建镜像的方法:docker commit 命令与 Dockerfile 构建文件。日常使用中推荐通过后者(Dockerfile)来构建镜像,下面通过样例进行演示。
(1)Dockerfile 其实是一个文本文件,记录了镜像构建的所有步骤。我们可以通过 vi 命令创建它。
1 |
|
(2)Dockerfile 里的内容如下:
1 2 |
|
(3)根据前面定义的构建步骤,需要将一个外部文件复制到镜像中。所有我们在同级目录下创建一个 index.html 文件,内容如下:
1 |
|
(1)运行 docker build 命令开始构建镜像:参数说明:
1 |
|
(2)上面执行后会显示出详细的构建过程。
(1)下面我们使用 docker run 命令运行我们构建的自定义镜像:
1 |
|
(2)运行后我们使用浏览器访问,可以看到这个 index.html 确实已经包含在这个镜像中。
当我们执行 docker build 命令制作镜像时,使用 -t 参数为镜像取个名字。实际上一个特定镜像的名字由两部分组成:repository 和 tag。其中 tag 常用于描述镜像的版本信息。
(1)上面样例中我们没有特别指定 tag:
1 |
|
(2)那么就会默认使用 latest,即上面效果相当于:
1 |
|
(1)tag 常用于描述镜像的版本信息:
1 |
|
(2)当然 tag 也可以是任意字符串:
1 |
|
(1)我们可以通过 docker tag 命令方便地给现有的镜像打 tag,比如下面将 latest 打上 3.1.0 的 tag。
1 |
|
(2)又比如下面将 latest 移到 4.1.0
1 |
|
用于指定基础镜像。如果不以任何镜像为基础,那么写法为:FROM scratch。
设置镜像的作者,可以是任意字符串。
将文件从 build context 复制到镜像。COPY 支持如下两种形式:
注意:src 只能指定 build context 中的文件或目录。
与 COPY 类似,从 build context 复制文件到镜像。不同的是,如果 src 是归档文件(tar、zip、tgz、xz 等),文件会被自动解压到 dest。
设置环境变量,环境变量可被后面的指令使用。下面是一个设置和使用的样例:
1 2 |
|
指定容器中的进程会监听某个端口,Docker 可以将该端口暴露出来。
1 |
|
用于指定持久化目录,实现挂载功能,授权访问从容器内到主机上的目录。用于 containers 之间共享数据,将本地文件夹或者其他容器中的文件夹挂在到这个容器中等。具体用法可以参考我之前写的一篇文章:
为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录。
1 |
|
(1)RUN 指令将在当前镜像基础上执行指定命令(即在最顶部执行命令),并提交为新的镜像,也就是多少个 RUN 就构建了多少层镜像。
(2)RUN 指令通常用于安装应用和软件包。下面是使用 RUN 安装多个包的例子:
1 2 3 4 5 6 |
|
(1)CMD 是构建容器后调用,也就是在容器启动时才进行调用。
注意:Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。
(2)CMD 指令允许用户指定容器的默认执行的命令,CMD 命令会在容器启动且 docker run 没有指定其他命令时运行。
1 |
|
(3)如果 docker run 后面带上其它参数,那么 CMD 会被忽略掉。
(1)ENTRYPOINT 和 CMD 很像:
(2)ENTRYPOINT 与 CMD 不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 dokcer run 时指定了其它命令。
(3)如果我们在 Dockerfile 中同时写了 ENTRYPOINT 和 CMD,并且 CMD 指令不是一个完整的可执行命令,那么 CMD 指定的内容将会作为 ENTRYPOINT 的参数。
1 2 3 |
|
(4)如果我们在 Dockerfile 种同时写了 ENTRYPOINT 和 CMD,并且 CMD 是一个完整的指令,那么它们两个会互相覆盖,谁在最后谁生效。
比如下面 ls -al 将会执行,top -b 则不会执行
1 2 3 |
|