基于 Dockerfile 的构建指令
-
基本
-
FROM- 指定base镜像
-
WORKDIR- 指定后面指令在
容器内的工作目录- 指令中的 dest相对路径 会根据这个目录 组合扩展成 绝对路径
- 好处
- 避免了
RUN cd … && do-something的难看写法
- 避免了
- 指定后面指令在
-
ENV- 设置环境变量,可以被紧跟其后的命令使用
ENV MY_VERSION RUN apt-get install -y mypackage=$MY_VERSION
- 设置环境变量,可以被紧跟其后的命令使用
-
-
文件操作
-
COPY- 将文件从 build context 复制到镜像
- 下面的 src 只能指定 build context 中的文件和目录
- 两种书写方式
- Shell格式
COPY src dest - Exec格式
COPY ["src", "dest"]
- Shell格式
- 将文件从 build context 复制到镜像
-
ADD- 也是将文件从 build context 复制到镜像
- 区别在于,如果 src 是归档文件(tar、zip等),会被自动解压到 dest
-
-
指令运行
-
先搞懂 Shell格式 和 Exec格式 的区别
Shell格式<instruction> <command>- 例子1
ENV name Mike ENTRYPOINT echo "HEllo, $name"- 底层会调用 shell (即
/bin/sh -c ...) - 会解析变量
- 输出
Hello, Mike
- 底层会调用 shell (即
- 例子1
- 【推荐,可读性强】
Exec格式<instruction> ["executable", "param1", "param2", ...]- 例子2
ENV name Mike ENTRYPOINT ["/bin/echo", "Hello, $name"]- 默认不会调用shell
- 输出
Hello, $name
- 例子3
ENV name Mike ENTRYPOINT ["/bin/sh", "-c", "/bin/echo", "Hello, $name"]- 这样指定才会调用shell
- 输出
Hello, Mike
- 例子2
-
RUN- 指定
构建时在容器中要运行的命令 - 常用于安装软件
- 注意,对于ubuntu,要这样安装
RUN apt-get update && apt-get install -y 包名- 为什么不能分开?
- 因为分开会导致
RUN apt-get update这一层存在缓存,这个缓存有可能是很久以前的,后面安装的就不是最新的包
- 注意,对于ubuntu,要这样安装
- 指定
-
CMD- 指定
等容器启动时运行的命令- 可以有多个 CMD,但只有最后一个生效
- 两种用途
- 直接指定默认命令
CMD ["executable", "param1", "param2", ...]- 命令存在失效的可能,比如docker run命令最后加上新的命令
/bin/bash时
- 命令存在失效的可能,比如docker run命令最后加上新的命令
- 为 ENTRYPOINT 指令提供默认参数
CMD ["param1", "param2", ...]- 参数也存在失效的可能,比如docker run命令最后加上新的参数
- 例子
ENTRYPOINT ["/bin/echo", "Hello"] CMD ["world"]- 当容器通过
docker run it 镜像名启动时,输出Hello world - 当容器通过
docker run it 镜像名 Mike启动时,输出Hello Mike
- 当容器通过
- 直接指定默认命令
- 指定
-
ENTRYPOINT- 也是指定
等容器启动时运行的命令- 也是可以有多个 ENTRYPOINT,但只有最后一个生效
- 一种用途
- 一定会被执行,不会失效,不管docker run命令最后加什么命令和参数
- 也是指定
-
-
不常用
EXPOSE- 指定暴露给同一networks下的其他容器的端口
EXPOSE 3000
- 指定暴露给同一networks下的其他容器的端口
ARG- 指定Dockerfile在构建过程的临时变量(它与ENV有区别,因为不会出现在容器运行的时候)
- 比如把3000赋值给port变量,后面用美元符号可多次引用
ARG port=3000 EXPOSE $port - 另一种等价的指定方式,就是通过yml文件,在build的内部指定args,内部可含多个ARG变量,这样可以引用真正的.env文件中的内容