Dockerfile定制镜像入门

参考文档

简单案例

Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

在一个空白目录中,建立一个文本文件,并命名为 Dockerfile:

1 $ mkdir mynginx
2 $ cd mynginx
3 $ touch Dockerfile

其内容为:

1 FROM nginx
2 RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

涉及到了两条指令,FROM 和 RUN。

FROM 指定基础镜像

一个 Dockerfile中 FROM 是必备的指令,并且必须是第一条指令。

如果不指定镜像基础,这可以使用如下:

1 FROM scratch

如果以 scratch 为基础镜像的话,意味着不以任何镜像为基础,接下来所写的指令将作为镜像第一层开始存在。

对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 FROM scratch 会让镜像体积更加小巧。

RUN 执行命令

RUN 指令是用来执行命令行命令的。由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一。其格式有两种:

  • shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。刚才写的 Dockerfile 中的 RUN 指令就是这种格式。
1 RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
  • exec 格式:RUN ["可执行文件", "参数1", "参数2"],这更像是函数调用中的格式
    一个 RUN 指令,并使用 && 将各个所需命令串联起来。将7 层,简化为了 1 层。

Dockerfile 支持 Shell 类的行尾添加 \ 的命令换行方式,以及行首 # 进行注释的格式。

构建镜像

在 Dockerfile 文件所在目录执行:

1 $ docker build -t nginx:v3 .

使用了 docker build 命令进行镜像构建。其格式为:

1 docker build [选项] <上下文路径/URL/->

此时输入如下命令即可查看自己构建的镜像:

1 docker images

镜像构建上下文(Context)

docker build 命令最后有一个 . (点) , . 表示当前目录,而 Dockerfile 就在当前目录,但是其实 . 表示的是上下文路径,该路径指的是Dockerfile文件所在路径(指定构建镜像上下文的路径)下的内容 打包发送到docker server 中 并解压后所在的目录,构建镜像的过程都是调用一组 REST API 与 Docker 引擎交互,从而完成各种功能。

案例:假如在Dockerfile 文件所在目录下有一个文件 test.txt , 然后在Dockerfile 中编写如下:

1 From tomcat
2 COPY test.txt /usr/local/tomcat/webapps/ROOT/

然后在Dockerfile 文件所在目录下 构建镜像:

1 docker build -t tomcat-v1 .

可以看到构建过程为:

1 Sending build context to Docker daemon  3.072kB
2 Step 1/2 : From tomcat
3  ---> 238e6d7313e3
4 Step 2/2 : COPY test.txt /usr/local/tomcat/webapps/ROOT/
5  ---> 74132bcad66e
6 Successfully built 74132bcad66e

之后运行构建的镜像即可在相关路径下找到copy的文件,因为该文件随着上下文路径发送到服务端,可以copy到

Dockerfile 其他的常用指令

上面已经讲过了from 和 run(每个run命令都会启动一个容器) ,下面举出一些其他的

WORKDIR
格式:

  • WORKDIR <工作目录路径>
    使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。在Dockerfile中的命令,每一行都是启动一个进程,互相之间没有递进关系,不可能继承前一层构建过程中的内存变化。因此当前一层将文件更改路径之后,在下一层想继续操作该文件,需要先将工作目录指定到文件所在目录,因此也可以在 From 命令后就指定工作目录,方便下面其他层的操作。

COPY
格式:

  • COPY <源路径>... <目标路径>
  • COPY ["<源路径1>",... "<目标路径>"]
    就是拷贝一个目录的文件到另一个目录

ADD
格式:

  • ADD <源路径>... <目标路径>
  • ADD ["<源路径1>",... "<目标路径>"]
    主要用于将文件自动解压缩到一个目录中,ADD 指令会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。

可以遵循这样的原则,所有的文件复制均使用 COPY 指令,仅在需要自动解压缩的场合使用 ADD。

EXPOSE
格式:

EXPOSE <端口1> [<端口2>...]

暴露端口,也就是声明构建的镜像所开放的端口,在启动容器时,可以通过宿主机的端口映射到构建镜像时暴露的端口,从而访问相关服务

端口映射方式:

-p 宿主机端口:容器端口 例:docker run -p 80:8080 tomcat 使用80端口访问会映射到8080端口
-P 是指宿主机会自动随机映射 EXPOSE 的端口 例docker run -P tomcat 会扫描tomcat暴露的端口,即默认的8080
注意:EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。

CMD
格式:

  • shell 格式:CMD <命令>
  • exec 格式:CMD ["可执行文件", "参数1", "参数2"...]

CMD 指令就是用于指定默认的容器主进程的启动命令的。 例如:

1 CMD [ "curl", "-s", "http://ip.cn" ]

待补充。。。