Snakemake结合Singularity使用时如何实现任意路径文件目录创建
Snakemake 调用 Singularity(现也叫Apptainer)运行容器时,默认只会把当前工作流的工作目录挂载为可读写模式,宿主机器上的其他路径要么以只读模式挂载、要么不做挂载,因此写入工作目录外的路径会触发Read-only file system报错。
你示例中touch ~/hello.txt能正常执行,是因为Snakemake启动容器时会将容器内的HOME变量默认指向工作目录,实际文件还是写在工作目录内,并没有写入宿主的真实家目录。
按需绑定可写路径(最推荐,安全性最高)
这是最稳妥的方案,仅给需要写入的目标路径开放权限,符合最小权限原则。
启动Snakemake时通过--singularity-args参数传入Singularity的路径绑定规则即可,绑定格式为宿主绝对路径:容器内对应路径:rw,末尾的rw标记代表可读写,多个路径用逗号分隔。
比如需要往宿主的/home/user目录写文件,启动命令添加如下参数:
snakemake --use-singularity --singularity-args "--bind /home/user:/home/user:rw"
如果还有其他需要写入的路径,例如/data/result目录,直接扩展绑定参数即可:
snakemake --use-singularity --singularity-args "--bind /home/user:/home/user:rw,/data/result:/data/result:rw"
如果不想每次执行命令都携带该参数,可以把配置写到Snakemake工作流配置或者运行profile中,实现全局生效:
# 写入工作流config.yaml或者profile配置文件 singularity: args: "--bind /home/user:/home/user:rw,/data/result:/data/result:rw"
单规则单独配置绑定路径
如果只有个别规则需要写入工作目录外的路径,没必要全局开放权限,直接在对应规则的params字段单独传入该规则的Singularity绑定参数即可:
rule write_external_file: container: "docker://some_image" params: singularity_args = "--bind /home/user:/home/user:rw" shell: "touch /home/user/hello.txt"
全路径可写(极度不推荐)
如果确实有特殊场景需要给容器开放所有宿主路径的写入权限,可以直接将宿主根目录以可读写模式挂载进容器。注意:该操作会完全破坏容器隔离性,容器内操作可以任意修改、删除宿主系统文件,有极高安全风险,非必要绝对不要使用:
snakemake --use-singularity --singularity-args "--bind /:/:rw"
- Singularity容器默认使用启动Snakemake的宿主用户身份运行,就算给路径加了
rw挂载,如果你在宿主系统本身没有目标路径的写入权限,容器内依然无法写入文件,需要先在宿主上给当前用户开放目标路径的写权限。 - 不要随意添加
--privileged参数启动容器,会放开设备访问等一堆高危权限,完全没有必要。
内容的提问来源于stack exchange,提问作者yippingAppa

