Dockerfile中多FROM指令使用顺序错误致命令缺失求助
解决Docker多阶段构建中同时使用g++和bash工具的问题
这个问题我之前也踩过坑,核心原因是没搞明白Docker多阶段构建的本质:每个FROM指令都会启动一个全新的独立构建阶段,前一个阶段安装的软件、生成的文件都不会自动传递到下一个阶段,除非你主动用COPY --from=...复制需要的内容。
为什么你的两次尝试都失败了?
- 第一次尝试:最后一个
FROM是alpine:3.9,这意味着最终的镜像基于alpine,而你之前在gcc:7.4阶段的所有操作都不会被保留,alpine里默认没有g++,所以报错g++: not found。 - 第二次尝试:最后一个
FROM是gcc:7.4,这个阶段完全独立于前面的alpine阶段,alpine里安装的bc等工具根本没被带到gcc镜像里,所以脚本执行时找不到bc。
两种可行的解决方案
方案1:直接基于gcc镜像安装所需工具
如果你不需要alpine的极致轻量化,最简单的方式就是在gcc:7.4镜像上直接安装bash、bc等工具。因为gcc镜像基于Debian/Ubuntu,用apt-get安装即可:
FROM gcc:7.4 # 更新源并安装所需工具,清理缓存减小镜像体积 RUN apt-get update && apt-get install -y --no-install-recommends \ bash gawk sed grep bc coreutils \ && rm -rf /var/lib/apt/lists/* # 在这里执行你的g++编译命令 RUN g++ -o your_app your_source.cpp # 运行你的脚本(此时bc等工具已存在) COPY test.sh /test/test.sh RUN chmod +x /test/test.sh CMD ["/test/test.sh"]
方案2:用多阶段构建兼顾轻量化和编译能力
如果想要alpine镜像的轻量优势,同时需要gcc的编译能力,可以把编译和运行分成两个阶段:
# 第一阶段:编译阶段(用gcc镜像构建程序) FROM gcc:7.4 AS builder # 复制你的源代码到容器内 COPY ./src /src WORKDIR /src # 编译生成可执行文件 RUN g++ -o my_app main.cpp # 第二阶段:运行阶段(用alpine镜像,仅保留运行所需的东西) FROM alpine:3.9 # 安装运行脚本需要的bash、bc等工具 RUN apk add --no-cache bash gawk sed grep bc coreutils # 从编译阶段复制已经编译好的可执行文件 COPY --from=builder /src/my_app /usr/local/bin/ # 复制你的脚本并赋予执行权限 COPY test.sh /test/test.sh RUN chmod +x /test/test.sh # 启动脚本 CMD ["/test/test.sh"]
这种方式既利用了gcc镜像的编译能力,又最终得到了体积更小的alpine镜像,是多阶段构建的典型用法。
内容的提问来源于stack exchange,提问作者François Rioult
相关产品推荐
相关产品推荐

