Docker 入门教程(3)——Dockerfile
Dockerfile
Dockerfile是一个文本文件,用来定制镜像。
镜像是分层存储的,前一层会是下一层的基础。而镜像的定制就是定制每一层镜像在上一层做了什么改变。
Dockerfile其内包含一条条指令,每条指令构建一层,定义对上一层做了什么改变。
以定制spring cloud的eureka注册中心为例:
工程结构为idea默认生成的eureka工程,使用maven package 生成jar包:
Dockerfile如下:
#以java8为父镜像
FROM java:8
#将maven打包的jar包复制到/register.jar
ADD ./target/register-0.0.1-SNAPSHOT.jar /register.jar
#暴露容器的8761端口
EXPOSE 8761
#执行java -jar /register.jar命令
CMD ["java", "-jar", "/register.jar"]
在当前目录执行docker build -t register .
可以看到每一条指令都生成了一个镜像,我们可以使用docker images -a
查看所有的镜像。
但我们再次执行docker build -t register .
时会发现每一条指令都显示Using cache
,这就是镜像分层存储的意义——构建缓存。
常用指令
- FROM 指定基础镜像
- RUN 执行命令
- RUN
,如: RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
- RUN ["可执行文件", "参数1", "参数2"]
- RUN
- COPY 复制文件
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
- 源路径可以是多个,甚至可以是通配符,其通配符规则要满足 Go 的
filepath.Match
规则
- ADD 更高级的复制文件
ADD
与COPY
基本一致,区别在ADD源路径可以是url,且如果<源路径>
为一个tar
压缩文件的话,压缩格式为gzip
,bzip2
以及xz
的情况下,ADD
指令将会自动解压缩这个压缩文件到<目标路径>
去。- 在 Docker 官方的 Dockerfile 最佳实践文档 中要求,尽可能的使用
COPY
,因为COPY
的语义很明确,就是复制文件而已,而ADD
则包含了更复杂的功能,其行为也不一定很清晰。最适合使用ADD
的场合,就是所提及的需要自动解压缩的场合。
- CMD 容器启动命令
- ENTRYPOINT 入口点
ENTRYPOINT
与CMD
的目的一样,都是指定容器启动程序与参数。- 当指定了
ENTRYPOINT
后,CMD
的含义就发生了改变,不再是直接的运行其命令,而是将CMD
的内容作为参数传给ENTRYPOINT
指令
- ENV 设置环境变量
- ARG 构建参数
- VOLUME 定义匿名卷
- EXPOSE 暴露端口
详细介绍,可以查看Docker——从入门到实践
镜像构建上下文
上面我们构建镜像时使用docker build -t register .
,.
就是在指定构建的上下文,其作用在于执行docker build
命令时会将该目录下的内容打包交给 Docker 引擎,以便后续的ADD
/COPY
找到需要复制的文件。
下图红线标记可以看出发送了43mb的文件给Docker引擎。
ps:只会打包构建上下文下的文件和文件夹,不会打包父目录,所以使用ADD ../register.jar
会报找不到文件。
参考资料
一个菜鸟程序员的学习笔记,有问题欢迎指正