Docker系列- 自定义Docker镜像: Dockerfile

1,132 阅读5分钟

自定义Docker镜像: Dockerfile

Docker系列回顾

为什么要自定义镜像

从前面的几节我们知道, Docker中存在很多镜像, 我们下载下来就可以直接用。

不过也存在这么一种情况:

  • 我们每次下载的镜像都需要在原镜像的基础上进行配置, 每次都需要重复配置, 感觉很麻烦

如果有这么一种方式可以让我们只配置一次, 以后就直接用, 省下来配置的时间我们去摸鱼, 这样子不香么!!

别急, Docker很贴心了为我们提供了解决方案, 我们来看下

使用 Dockerfile 定制镜像

什么是Dockerfile

Dockerfile 是一个文本文件,其内包含了一条条的 指令, 通过该文件我们可以定制出我们我们需要的镜像

开始定制

Docker入门介绍 中的Tomcat为例, 看看我在其中做了什么

#基础镜像
FROM tomcat

##定义工作目录
ENV CONF_PATH /usr/local/tomcat/conf
#
##定义conf文件名
ENV SERVER_CONF_FILE_NAME server.xml
ENV TOMCAT_USER_FILE_NAME tomcat-users.xml
#
##删除原有配置文件
RUN rm $CONF_PATH/$SERVER_CONF_FILE_NAME \
  && rm $CONF_PATH/$TOMCAT_USER_FILE_NAME

#
##复制新的配置文件
COPY ./$SERVER_CONF_FILE_NAME $CONF_PATH/
COPY ./$TOMCAT_USER_FILE_NAME $CONF_PATH/
#
##给shell文件赋读权限
RUN chmod a+x $CONF_PATH/$SERVER_CONF_FILE_NAME \
  && chmod a+x $CONF_PATH/$TOMCAT_USER_FILE_NAME

EXPOSE 8099

我们一行行来拆解:

  • FROM tomcat
  1. 定制镜像其实就是已一个镜像为基础, 在这个基础上进行定制, 所以 FROM 就是指定基础镜像的指令, 而且是必须指定且必须是第一条指令

  2. 后面的 tomcat 就是基础镜像的名称, 格式为: 镜像名称:标志。 默认会省略最新版本的tag

  • ENV CONF_PATH /usr/local/tomcat/conf

    1. ENV 是设置环境变量, 相当于代码中的变量, 设置了环境变量之后, 后面可以直接使用

    2. ENV 设置有两个格式:

    • ENV key value

    • ENV key1=value1 key2=value2

    1. 建议在使用的时候, 使用 ENV 设置环境变量, 减少以后修改的内容
  • RUN rm $CONF_PATH/$SERVER_CONF_FILE_NAME && rm $CONF_PATH/$TOMCAT_USER_FILE_NAME

    1. RUN 指令是用来执行命令行命令的, 由于命令行的强大能力,RUN 指令在定制镜像时是最常用的指令之一

    2. 简单一点理解, RUN 指令就相当于执行我们在命令行中的命令一样

    3. RUN 指令的两个格式

    • shell 格式:RUN <命令>, 就是我们在上面写的格式

    • exec 格式:RUN ["可执行文件", "参数1", "参数2"]

注意点

很多人在使用 RUN 指令的时候, 会把每一个命令都对应一个 RUN 。 不是说这样不对, 而是这样完全没有意义,在最后生成镜像的时候, 也会装很多不需要的东西, 建议大家采用上面的方式来书写

  • COPY ./$SERVER_CONF_FILE_NAME $CONF_PATH/

    1. COPY 指令, 见名知意, 就是复制命令, 意思就是将该文件复制到镜像指定的目录下
  • EXPOSE 8099

    1. EXPOSE指令是声明运行时容器提供服务端口, 也就是容器暴露出来提供给我们映射的端口号

好, 到此上面的指令就介绍完成了, 下面我们来看下如何执行

docker build -t 名称:tag .

构建镜像过程

这样我们就构建了我们的第一个自己的镜像, 我们来运行看看

docker run -d -p 8099:8099 --name tomcat8099 sanq_cab/tomcat8:1.0

运行成功

已经成功启动并且运行了我们创建的镜像, 可能大家会注意到, build 命令最后有一个 ., 这里牵扯到一个镜像上下文的概念, 给大家找一个更加官方的介绍: 点击传送门

Dockerfile其他常用指令

看了上面的指令, 是不是觉的很简单啊, 那么我们再看看其他的指令吧

  • ADD 指令

这个指令在本质上和COPY是一样的, 不过相对比COPY指令来说, ADD 指令更加的强大

  • 比如 <源路径> 可以是一个 URL,这种情况下,Docker 引擎会试图去下载这个链接的文件放到 <目标路径> 去。
  • 如果 <源路径> 为一个 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,ADD 指令将会自动解压缩这个压缩文件到 <目标路径> 去。
ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
  • CMD 容器启动命令

CMD指令 就是用于指定默认的容器主进程的启动命令。格式和 RUN 指令一样

  • ARG 容器启动命令

    构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境的环境变量,在将来容器运行时是不会存在这些环境变量的。但是不要因此就使用 ARG 保存密码之类的信息,因为 docker history 还是可以看到所有值的。

    Dockerfile 中的 ARG 指令是定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build 中用 --build-arg <参数名>=<值> 来覆盖。

  • VOLUME 定义匿名卷

    • 该指令是为了防止我们在运行的时候忘记挂载目录,所以在定制镜像的时候是先指定一个匿名卷, 这样在运行时如果用 户不指定挂载,其应用也可以正常运行,并且不会向容器存储层写入大量数据。 保证容器存储层的无状态化

    • 格式: VOLUME 目录

  • WORKDIR 指定工作目录

    • 使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。

    • 格式: WORKDIR <工作目录路径>

其实以上这些指令在我们使用中用的比较常用, 如果还有其他指令的话, 大家可以参考官方文档, 下面给出地址

参考文档