如何通过Podman在Dockerfile中复制符号链接目录?
复制外部conda环境到容器的Podman构建问题及解决方法
问题场景
在橡树岭国家实验室Summit超级计算机环境下,尝试将构建目录外的复杂conda环境复制到容器镜像中,使用的Dockerfile如下:
FROM code.ornl.gov:4567/olcfcontainers/olcfbaseimages/mpiimage-centos-cuda RUN mkdir /app # conda是指向当前工作目录外conda环境层级的本地符号链接 COPY conda/ /app RUN cd /app && conda activate /app/conda
执行Podman构建时出现错误:
STEP 6: COPY conda /app Error: error building at STEP "COPY conda /app": error adding sources [/gpfs/alpine/bif135/scratch/mcoletti/deepmd_on_Summit/conda]: error reading "/gpfs/alpine/bif135/scratch/mcoletti/deepmd_on_Summit/conda": error during bulk transfer for copier.request{Request:"GET", Root:"/", preservedRoot:"/gpfs/alpine/bif135/scratch/mcoletti/deepmd_on_Summit", rootPrefix:"/gpfs/alpine/bif135/scratch/mcoletti/deepmd_on_Summit", Directory:"/", preservedDirectory:"/gpfs/alpine/bif135/scratch/mcoletti/deepmd_on_Summit", Globs:[]string{"/conda"}, preservedGlobs:[]string{"/gpfs/alpine/bif135/scratch/mcoletti/deepmd_on_Summit/conda"}, StatOptions:copier.StatOptions{CheckForArchives:false, Excludes:[]string(nil)}, GetOptions:copier.GetOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), Excludes:[]string(nil), ExpandArchives:false, ChownDirs:(*idtools.IDPair)(0xc0004a73d0), ChmodDirs:(*os.FileMode)(nil), ChownFiles:(*idtools.IDPair)(0xc0004a73e0), ChmodFiles:(*os.FileMode)(nil), StripSetuidBit:true, StripSetgidBit:true, StripStickyBit:false, StripXattrs:false, KeepDirectoryNames:false, Rename:map[string]string(nil)}, PutOptions:copier.PutOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), DefaultDirOwner:(*idtools.IDPair)(nil), DefaultDirMode:(*os.FileMode)(nil), ChownDirs:(*idtools.IDPair)(nil), ChmodDirs:(*os.FileMode)(nil), ChownFiles:(*idtools.IDPair)(nil), ChmodFiles:(*os.FileMode)(nil), StripXattrs:false, IgnoreXattrErrors:false, IgnoreDevices:false, NoOverwriteDirNonDir:false, Rename:map[string]string(nil)}, MkdirOptions:copier.MkdirOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), ChownNew:(*idtools.IDPair)(nil), ChmodNew:(*os.FileMode)(nil)}}: copier: get: lstat "/conda"("/gpfs/alpine/proj-shared/chm174/conda"): lstat /gpfs/alpine/proj-shared/chm174/conda: no such file or directory
注:报错中提到的路径实际存在,Summit超算环境可能存在本地特殊配置限制。
解决方法
1. 直接使用真实路径调整构建上下文
Podman的COPY指令无法直接跟随指向构建上下文外的软链接,可直接使用conda环境的真实路径,并调整构建上下文范围:
- 切换到conda环境所在的父目录执行构建,或用
--context参数指定包含该环境的目录作为构建上下文 - 修改Dockerfile中的COPY路径:
FROM code.ornl.gov:4567/olcfcontainers/olcfbaseimages/mpiimage-centos-cuda RUN mkdir /app # 直接引用conda环境的真实路径,确保该路径在构建上下文内 COPY ./conda /app/conda RUN cd /app && conda activate /app/conda
2. 打包conda环境后复制
若无法调整构建上下文,先将外部conda环境打包为压缩包,再复制到容器内解压:
- 在构建目录外执行打包命令:
tar -czf conda_env.tar.gz /gpfs/alpine/proj-shared/chm174/conda
- 将压缩包移至构建目录内,修改Dockerfile:
FROM code.ornl.gov:4567/olcfcontainers/olcfbaseimages/mpiimage-centos-cuda RUN mkdir /app COPY conda_env.tar.gz /app/ RUN cd /app && tar -xzf conda_env.tar.gz && rm conda_env.tar.gz RUN cd /app && conda activate /app/conda
3. 利用Summit超算挂载特性(需验证权限)
Summit的GPFS文件系统可能存在权限或挂载限制,可尝试构建阶段挂载外部路径:
- 执行构建时挂载conda环境路径:
podman build --volume /gpfs/alpine/proj-shared/chm174/conda:/tmp/conda -f Dockerfile .
- 修改Dockerfile中的复制路径为挂载的临时路径:
FROM code.ornl.gov:4567/olcfcontainers/olcfbaseimages/mpiimage-centos-cuda RUN mkdir /app COPY /tmp/conda /app/conda RUN cd /app && conda activate /app/conda
内容的提问来源于stack exchange,提问作者Mark Coletti
相关产品推荐
相关产品推荐

