1. Dockerfile&.dockerignore

本系列文章对Docker的介绍均翻译自Docker官方英文文档,不会去其他博客东拼西抄。文中会穿插一些自己在使用中的踩坑经历和心得体会。如有错误,敬请批评指正。

1) Dockerfile

Dockerfile的作用,是通过文件中的一行行指令,来指导docker逐步完成镜像的创建。官方给出的Dockerfile格式如下所示:

# 注释(指令 参数)
INSTRUCTION arguments

指令并不区分大小写,但是通常情况下建议大写,以便和参数区分开。

在本节中,首先以我最近写的一个简单的Dockerfile作为示例,然后逐行解释每一条命令的含义。

FROM node:10.13.0
MAINTAINER yu
WORKDIR /workspace
ADD . /workspace
RUN npm install -g cnpm
RUN cnpm install
EXPOSE 8100
CMD ["node", "index.js"]
  • 第一行是万年不变的FROM,Dockerfile必须以FROM指令开头。在FROM中指定了你所需要的基础镜像,可以是UBUNTU,也可以像我这里一样是一个node镜像。这里因为我的特殊需求,指定了10.13.0版本的node,查看镜像发现大小达到了893MB,通常情况可以指定一个alpine版的node,短小精干,全是精华,只有区区几十MB而已;
  • MAINTAINER在官方文档中显示已弃用,不过目前大多数中文教程里都这么写。最新版本中推荐使用LABLE指令代替,例如上面这句可以写成LABLE maintainer="yu";
  • WORKDIR的作用是申明接下来命令的执行路径,可以理解成cd到目标路径下。
  • 这里ADD命令的意思是将当前目录下(除了dockerignore中排除的)所有文件,添加到/workspace目录下。这里也可以用COPY命令代替。相对而言,ADD命令更强大一些,并且能够添加远程目录下的文件。此外,还需注意,当路径中包含空格时,需要写成这样的格式ADD ["<src>",... "<dest>"]
  • RUN的意思想必不用解释了,就是运行一下后面的命令。由于使用npm指定registry依旧奇慢无比,我在这里安装了一个cnpm,会快很多,然后根据package.json的内容安装依赖包;
  • EXPOSE则声明了容器在运行时暴露的端口,可以通过EXPOSE 80/udp来指定协议,默认是tcp端口;
  • 茴香豆的茴有4种写法,而CMD则只有3种写法,上文那种是官方推荐的首选格式。在一个Dockerfile中,只能有一个CMD,若有多个则只会执行最后一行的CMD,毕竟上面还有个RUN可以帮你执行一大堆东西。

编写完成后,在当前目录下输入docker build -t demo .(注意左边这个小点点),docker就会在当前目录下寻找名为Dockerfile的文件,并根据其内容来建立一个镜像。如果要用其他目录下的Dockerfile,也可以通过-f参数来显式的指定Dockerfile文件的位置。

2) .dockerignore file

Dockerfile简单的说完了,再来聊一聊它的小伙伴——.dockerignore。.dockerignore这个文件,就相当于一份婚前协议:“这些东西是我的,即便结婚了你也不能碰。”

上面的Dockerfile中有一行ADD命令,在上面的解释中也说明了,在ADD过程中会将.dockerignore中声明的文件排除。.dockerignore的写法也非常简单,如下所示:

# 注释
# */temp*
node_modules

我这里的需求非常简单,将node_modules排除即可,稍复杂的需求,用Linux中的*和/描述文件即可,如第二行注释所示。

在这里将node_modules踢出去肯定不是我闲着无聊,必然是有原因的。首先,node_modules通常比较大,没必要搬来搬去,其次,上面的Dockerfile中调用了cnpm install命令,如果把node_modules文件搬过去的话,会报错。。。

两个file讲完了,很简单,没什么好总结的。下一篇会介绍build相关的命令和具体步骤。