这几天遇到个项目,需要在服务器上用到 Nextflow 流程运行一个Singularity镜像(singleron-RD/wf-single-cell)虽然服务器能联网,但因为某些众所周知的原因,Singularity(或 Apptainer)完全无法从 DockerHub 直接拉取所需镜像。倒腾了一下午,试了各种办法,终于搞定了,这里记录下最终可行的解决方案。
背景
在服务器上运行某Nextflow流程时,需要从以下两个镜像拉取容器:
docker://ontresearch/wf-single-cell:sha0fcdf10929fbef2d426bb985e16b81153a88c6f4docker://ontresearch/wf-common:sha91cd87900c86f05bf36d8c77b841b8fda5ecf3aa
但由于某些原因,所有 docker 系列的网站直连都打不开,直接拉取失败。
方案一:Mac上下载好镜像包再传给服务器(不可行)
一开始想在 Mac 上直接下载好镜像包,但是发现 M 系列芯片的 Mac 由于架构原因,并不支持直接安装 Singularity 或是 Apptainer。于是尝试在本地通过 Docker 启动一个运行 Apptainer 的环境再进行下载。
docker run -it --privileged \
-v $PWD:/data \
ghcr.io/apptainer/apptainer:latest bash
cd /data
apptainer pull ontresearch-wf-single-cell.sif docker://ontresearch/wf-single-cell:sha0fcdf10929fbef2d426bb985e16b81153a88c6f4
apptainer pull ontresearch-wf-common.sif docker://ontresearch/wf-common:sha91cd87900c86f05bf36d8c77b841b8fda5ecf3aa
然而问题在于,Mac(ARM 架构)上生成的 .sif 文件无法在服务器(x86 架构)上运行,会报出架构不匹配错误,因此此方法虽然能成功获得 sif 文件,但获取的文件在服务器上无法运行。。
方案二:通过 SSH 代理转发使用本地代理下载(可行)
因为不想在服务器上单独配置一套代理,发现可以通过 SSH 反向端口转发,让服务器直接使用 Mac 本地代理,从而顺利下载容器镜像,实现流程如下:
1. 建立 SSH 反向代理通道
假设本地代理端口为 6152,在连接服务器时建立反向映射:
ssh -p 22 -R 1080:127.0.0.1:6152 usr_name@remote_ip -t zsh
连接成功后,服务器可以通过 127.0.0.1:1080 访问外网。
2. 在服务器上设置代理环境变量
export https_proxy=http://127.0.0.1:1080
export http_proxy=http://127.0.0.1:1080
3. 在服务器上准备镜像存放目录
mkdir -p $HOME/containers && cd $HOME/containers
4. 使用 Singularity 拉取镜像
singularity pull ontresearch-wf-single-cell.sif docker://ontresearch/wf-single-cell:sha0fcdf10929fbef2d426bb985e16b81153a88c6f4
singularity pull ontresearch-wf-common.sif docker://ontresearch/wf-common:sha91cd87900c86f05bf36d8c77b841b8fda5ecf3aa
下载完成后,镜像文件保存在:
$HOME/containers/
5. 在 Nextflow 配置中使用本地 SIF 文件
为了避免 Nextflow 再次联网下载,可在 nextflow.config 中指定本地容器路径:
process {
withLabel: singlecell {
container = "$HOME/containers/ontresearch-wf-single-cell.sif"
}
withLabel: wf_common {
container = "$HOME/containers/ontresearch-wf-common.sif"
}
}
这样 Nextflow 会直接使用本地镜像文件,而不会再尝试从 DockerHub 获取。
五、总结
真是太费劲了!