Docker ONBUILD指令工作原理及构建后目标文件缺失问题求助
问题分析与解决
错误原因
你在Dockerfile2中使用了多阶段构建,但第一个构建阶段的内容没有被最终镜像继承:
- 第一个
FROM onbuilddemo:latest会触发该镜像的ONBUILD指令,将onbuilddemo.txt复制到这个阶段的/tmp目录下,但这个阶段只是一个临时的构建层; - 紧接着的第二个
FROM adoptopenjdk/openjdk8:jre8u352-b05-ea-ubuntu-nightly开启了全新的构建阶段,最终生成的镜像完全基于这个阶段的镜像,第一个阶段的所有内容(包括复制的文件)都不会被包含进去,所以容器中找不到/tmp/onbuilddemo.txt。
解决方案
根据你的需求,有三种可选的修正方式:
方式一:移除多阶段构建,直接基于onbuilddemo:latest构建
如果你的最终镜像可以基于centos7(即onbuilddemo:latest的基础镜像),直接修改Dockerfile2为:
FROM onbuilddemo:latest EXPOSE 8080 WORKDIR /root CMD ["npm", "start"]
构建时会自动执行ONBUILD指令,将onbuilddemo.txt复制到镜像的/tmp目录下。
方式二:多阶段构建下手动复制文件
如果必须使用adoptopenjdk作为最终基础镜像,可以保留多阶段构建,从第一个阶段复制文件到最终阶段:
# 第一个阶段:执行ONBUILD指令复制文件 FROM onbuilddemo:latest AS builder # 第二个阶段:基于adoptopenjdk构建最终镜像 FROM adoptopenjdk/openjdk8:jre8u352-b05-ea-ubuntu-nightly # 从第一个阶段复制已生成的文件到当前阶段 COPY --from=builder /tmp/onbuilddemo.txt /tmp/onbuilddemo.txt EXPOSE 8080 WORKDIR /root CMD ["npm", "start"]
方式三:直接在最终阶段复制本地文件
如果不需要依赖onbuilddemo:latest的ONBUILD逻辑,也可以直接在Dockerfile2中添加复制指令:
FROM adoptopenjdk/openjdk8:jre8u352-b05-ea-ubuntu-nightly # 直接从本地复制文件到镜像 COPY ./onbuilddemo.txt /tmp/onbuilddemo.txt EXPOSE 8080 WORKDIR /root CMD ["npm", "start"]
内容的提问来源于stack exchange,提问作者user2315104
相关产品推荐
相关产品推荐

