如何在单个Dockerfile中使用多镜像时避免前序镜像数据被覆盖
多FROM镜像内容丢失问题解决方案
问题原因
你遇到的多个FROM声明内容丢失是Docker多阶段构建的默认逻辑:前序FROM定义的是独立构建阶段,默认仅最后一个阶段的文件系统会作为最终镜像输出,前序阶段的内容不会自动带入后续阶段,因此你示例里的cuda环境不会出现在最终的python镜像基础上的容器里。
可行实现方案
方案1:选择适配的基础镜像后手动安装缺失组件
这是稳定性最高的方案,逻辑为挑选核心依赖对应的镜像作为基础层,手动在其之上安装另一套所需组件。你的场景核心依赖是cuda,直接以cuda镜像为基础安装Python3.8即可,示例如下:
FROM nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04 # 配置源并安装Python3.8 RUN apt update && apt install -y software-properties-common \ && add-apt-repository ppa:deadsnakes/ppa -y \ && apt update && apt install -y python3.8 python3.8-pip python3.8-distutils \ # 配置默认python指向3.8 && update-alternatives --install /usr/bin/python python /usr/bin/python3.8 1 \ && update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 CMD ["/bin/bash"]
方案2:多阶段构建主动拷贝前序镜像内容
如果你需要复用其他镜像内已编译好的组件,可以用COPY --from=语法主动把前序阶段的指定路径拷贝到最终镜像中,该方案需要你明确知晓所需组件的所有安装路径,避免漏掉动态库等依赖,示例如下:
# 第一阶段:定义python镜像层 FROM python:3.8.10 as python_base # 第二阶段:以cuda镜像为基础,拷贝python相关文件 FROM nvidia/cuda:10.2-cudnn8-devel-ubuntu18.04 # 拷贝python的可执行文件、库文件、头文件 COPY --from=python_base /usr/local/bin /usr/local/bin COPY --from=python_base /usr/local/lib /usr/local/lib COPY --from=python_base /usr/local/include /usr/local/include # 更新动态库缓存 RUN ldconfig CMD ["/bin/bash"]
注意:方案2仅适合依赖简单的轻量组件,涉及cuda、系统底层库这类复杂依赖时优先选择方案1,避免出现运行时找不到依赖的异常。
内容的提问来源于stack exchange,提问作者Pro_gram_mer
相关产品推荐
相关产品推荐

