ONBUILD 为他人做嫁衣裳

格式:ONBUILD <其它指令>

ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN, COPY 等,而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去构建下一级镜像的时候才会被执行。

Dockerfile 中的其它指令都是为了定制当前镜像而准备的,唯有 ONBUILD 是为了帮助别人定制自己而准备的。

假设我们要制作 Node.js 所写的应用的镜像。我们都知道 Node.js 使用 npm 进行包管理,所有依赖、配置、启动信息等会放到 package.json 文件里。在拿到程序代码后,需要先进行 npm install 才可以获得所有需要的依赖。然后就可以通过 npm start 来启动应用。因此,一般来说会这样写 Dockerfile

FROM node:slim
RUN mkdir /app
WORKDIR /app
COPY ./package.json /app
RUN [ "npm", "install" ]
COPY . /app/
CMD [ "npm", "start" ]

把这个 Dockerfile 放到 Node.js 项目的根目录,构建好镜像后,就可以直接拿来启动容器运行。但是如果我们还有第二个 Node.js 项目也差不多呢?好吧,那就再把这个 Dockerfile 复制到第二个项目里。那如果有第三个项目呢?再复制么?文件的副本越多,版本控制就越困难,让我们继续看这样的场景维护的问题。

如果第一个 Node.js 项目在开发过程中,发现这个 Dockerfile 里存在问题,比如敲错字了、或者需要安装额外的包,然后开发人员修复了这个 Dockerfile,再次构建,问题解决。第一个项目没问题了,但是第二个项目呢?虽然最初 Dockerfile 是复制、粘贴自第一个项目的,但是并不会因为第一个项目修复了他们的 Dockerfile,而第二个项目的 Dockerfile 就会被自动修复。

那么我们可不可以做一个基础镜像,然后各个项目使用这个基础镜像呢?这样基础镜像更新,各个项目不用同步 Dockerfile 的变化,重新构建后就继承了基础镜像的更新?好吧,可以,让我们看看这样的结果。那么上面的这个 Dockerfile 就会变为:

FROM node:slim
RUN mkdir /app
WORKDIR /app
CMD [ "npm", "start" ]

这里我们把项目相关的构建指令拿出来,放到子项目里去。假设这个基础镜像的名字为 my-node 的话,各个项目内的自己的 Dockerfile 就变为:

FROM my-node
COPY ./package.json /app
RUN [ "npm", "install" ]
COPY . /app/

基础镜像变化后,各个项目都用这个 Dockerfile 重新构建镜像,会继承基础镜像的更新。

那么,问题解决了么?没有。准确说,只解决了一半。如果这个 Dockerfile 里面有些东西需要调整呢?比如 npm install 都需要加一些参数,那怎么办?这一行 RUN 是不可能放入基础镜像的,因为涉及到了当前项目的 ./package.json,难道又要一个个修改么?所以说,这样制作基础镜像,只解决了原来的 Dockerfile 的前4条指令的变化问题,而后面三条指令的变化则完全没办法处理。

ONBUILD 可以解决这个问题。让我们用 ONBUILD 重新写一下基础镜像的 Dockerfile:

FROM node:slim
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
ONBUILD COPY . /app/
CMD [ "npm", "start" ]

这次我们回到原始的 Dockerfile,但是这次将项目相关的指令加上 ONBUILD,这样在构建基础镜像的时候,这三行并不会被执行。然后各个项目的 Dockerfile 就变成了简单地:

FROM my-node

是的,只有这么一行。当在各个项目目录中,用这个只有一行的 Dockerfile 构建镜像时,之前基础镜像的那三行 ONBUILD 就会开始执行,成功的将当前项目的代码复制进镜像、并且针对本项目执行 npm install,生成应用镜像。

Dockerfile指令详解:ONBUILD 为他人作嫁衣裳相关推荐

  1. Dockerfile 指令详解1

    Dockerfile 指令详解 我们已经介绍了 FROM,RUN,还提及了 COPY, ADD,其实 Dockerfile 功能很强大,它提供了十多个指令.下面我们继续讲解其他的指令. COPY 复制 ...

  2. Dockerfile指令详解镜像构建实例说明

    Dockerfile使用总结 Dockerfile是用来构建镜像的文本文件,里面包含了一条条用于构建镜像所需的指令和说明. Dockerfiel文件中的每一层指令都是描述如何在上一层的基础上进行该层的 ...

  3. 【Docker】之 Dockerfile 指令详解

    目录 Dockerfile 基本结构 Dockerfile 指令 指定基础镜像 FROM 维护者信息 MAINTAINER 元数据标签 LABEL 设置环境变量 ENV 镜像构建参数 ARG 指定工作 ...

  4. Docker之Dockerfile 指令详解

    闲话不多说,dokerfile常用指令解析奉上 FROM 作用:指定基础镜像,必须放在DOckerfile的第一行,表示从哪个baseimage开始构建 格式: FROM <image>: ...

  5. Dockerfile 指令详解2

    ENV 设置环境变量 格式有两种: ENV <key> <value> ENV <key1>=<value1> <key2>=<val ...

  6. Docker学习——Dockerfile 指令详解(五)

    2019独角兽企业重金招聘Python工程师标准>>> 我们已经介绍了 FROM (指定基础镜像) , RUN(执行命令) ,还提及了 COPY , ADD ,其实 Dockerfi ...

  7. Dockerfile指令详解:WORKDIR 指定工作目录

    WORKDIR 指定工作目录 格式为 WORKDIR <工作目录路径>. 使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不 ...

  8. Docker学习总结(32)——Dockerfile指令详解

    1.ADD 复制文件 ADD指令用于复制文件,格式为: ADD <src>... <dest> ADD ["<src>",... "& ...

  9. Dockerfile指令详解: CMD 容器启动命令

    CMD 容器启动命令 CMD 指令的格式和 RUN 相似,也是两种格式: shell 格式:CMD <命令> exec 格式:CMD ["可执行文件", "参 ...

最新文章

  1. MySQL中字段字符集不同导致索引不能命中
  2. 专栏 | 基于 Jupyter 的特征工程手册:特征选择(五)
  3. BitmapUtil【缩放bitmap以及将bitmap保存成图片到SD卡中】
  4. php验证码函数 使用imagestring() imagefttext()设置字体大小
  5. nginx指定配置文件启动_【第1717期】Nginx入门指南
  6. 4th, Jan 2012 食物中毒惊魂
  7. 语法糖----C#的async和await
  8. .net项目引用ActiveX控件注意点
  9. GPU成为主流 NVIDIA GRID亮相Citrix Synergy 2017
  10. 电商项目的app学习笔记(三)-嵌套路由组件的实现
  11. 叫号系统是否需要服务器,银行排队叫号方法及系统、服务器及存储介质
  12. 【介绍了Sentaurus TCAD结构编辑器中可用的网格掺杂操作】
  13. 黑客常见攻击方法与防护方法
  14. 营销公众号该如何运营大纲
  15. latex normal是几号字_Latex 文本详细篇
  16. 快速将PDF转换为图片:免费的在线PDF转换器
  17. 全球海温数据NOAA Extended Reconstructed Sea Surface Temperature (SST) V5的时间解释
  18. 计算机硬件配置一般看什么CPU,电脑配置怎么看好坏
  19. 时间复杂度和空间复杂度简介
  20. 计算机程序工作日志,工作日志软件

热门文章

  1. C++ 标准库类型 string
  2. rust(36)-Rust and WebAssembly(3)
  3. 【NLP】基于预训练的中文NLP工具介绍:ltp 和 fastHan
  4. (视频+图文)机器学习入门系列-第10章 人工神经网络
  5. 【深度学习】Transformer长大了,它的兄弟姐妹们呢?(含Transformers超细节知识点)...
  6. 疫情之下,将业务迁移至云端会是一个正确的选择吗?
  7. 深度学习笔记 第五门课 序列模型 第二周 自然语言处理与词嵌入
  8. 以效率为根本,网易慢跑要做“另类”的TO B业务
  9. eclipse远程调试失败
  10. Scala基础知识笔记2