Docker镜像WORKDIR文件在Nextflow挂载容器时无法访问的技术求助
背景
我用以下Dockerfile构建了包含NLRexpress和hmmsearch的镜像,没有设置CMD,而是制作了可执行文件nlrexpress,这样镜像既能运行NLRexpress也能运行hmmsearch:
FROM ubuntu:18.04 ARG DEBIAN_FRONTEND=noninteractive WORKDIR /usr/local/src # Setting up general environment RUN apt-get -y update \ && apt-get install -y build-essential \ && apt-get install -y wget \ && apt-get install -y hmmer \ && apt-get install -y git \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* ## Installing miniconda ENV CONDA_DIR /opt/conda RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && \ /bin/bash ~/miniconda.sh -b -p /opt/conda ENV PATH=$CONDA_DIR/bin:$PATH # Installing NLRTracker RUN git clone https://github.com/eliza-m/NLRexpress WORKDIR /usr/local/src/NLRexpress # Setting up the conda environment and required variables RUN conda env create -f environment.yml && \ conda init bash && \ echo "conda activate nlrexpress" >> ~/.bashrc ENV PATH /opt/conda/envs/nlrexpress/bin:/usr/local/src/NLRexpress:$PATH ENV CONDA_DEFAULT_ENV nlrexpress RUN wget https://nlrexpress.biochim.ro/datasets/models.tar.gz && \ tar -xf models.tar.gz && \ rm models.tar.gz RUN echo "#!/bin/bash python nlrexpress.py" > nlrexpress && \ chmod +x nlrexpress
镜像构建正常,直接用docker run nlrexpress:latest nlrexpress测试能得到预期输出:
Usage: nlrexpress.py [OPTIONS] Try 'nlrexpress.py --help' for help. Error: Missing option '--input'.
但用Nextflow调用容器时出现错误:
python: can't open file '/path/to/workDir/ea/72bd9e660d0ce79944d8bdde3dd024/nlrexpress.py': [Errno 2] No such file or directory
我的Nextflow流程如下:
process NLRexpress { tag "$sample_id" publishDir params.PlantDir maxForks 1 container = 'dthorbur1990/nlrexpress:latest' executor = "local" input: tuple val(sample_id), path(peptides) output: path "*.short.output.txt" script: """ mkdir output nlrexpress \ --input ../${peptides} \ --outdir ./output \ --module ${params.NE_Modules} mv output/*.short.output.txt ./ """ }
我原以为设置WORKDIR后镜像会始终挂载到该路径,文件会自动可用,尝试设置环境变量也没用。不想把仓库克隆到Nextflow工作目录(每个流程都要下载模型,容器里已经有models目录了),而且hmmsearch在Nextflow和容器里能正常运行。
原因分析
Nextflow默认会将任务的工作目录(即你看到的/path/to/workDir/ea/...路径)挂载为容器的当前工作目录,这会覆盖Dockerfile中设置的WORKDIR。容器启动后,当前目录是挂载的工作目录,而不是镜像里的/usr/local/src/NLRexpress。你的nlrexpress脚本里用python nlrexpress.py是在当前目录找文件,自然找不到镜像中预安装的文件。
解决方案
修改Dockerfile中生成nlrexpress脚本的部分,用绝对路径调用nlrexpress.py,这样不管当前工作目录是什么,都能定位到正确的文件:
将Dockerfile中的这一段:
RUN echo "#!/bin/bash python nlrexpress.py" > nlrexpress && \ chmod +x nlrexpress
修改为:
RUN echo "#!/bin/bash python /usr/local/src/NLRexpress/nlrexpress.py" > nlrexpress && \ chmod +x nlrexpress
重新构建镜像后,Nextflow调用时就能正确找到nlrexpress.py文件,同时也不影响hmmsearch的使用。
另外,也可以通过设置环境变量来优化,比如在Dockerfile中添加:
ENV NLR_INSTALL_DIR /usr/local/src/NLRexpress
然后脚本里用python $NLR_INSTALL_DIR/nlrexpress.py,这样后续路径变更时只需修改环境变量即可,更灵活。
内容的提问来源于stack exchange,提问作者dthorbur

