3. Nextflow 安装与配置:环境搭建、版本管理与 DSL2 入门

好,聊完了审计追踪的理念和 RNA-seq 的可重复性价值,我们该动手了。这一章我把重点放在 Nextflow 的落地前准备上——说白了,就是怎么把工具装好、管住版本、然后尽快跑通一个最简单的 DSL2 工作流。

我个人习惯在开新项目前先花 10 分钟把环境理清楚,否则后期排查版本兼容性问题会很痛苦。嗯,我们一步步来。

3.1 环境前提:Java 11+ 与依赖

Nextflow 是基于 JVM(Java 虚拟机)的工具链,所以 Java 是第一关。我记得刚入行那会儿,有次在 HPC 上装 Nextflow,java -version 显示 Java 8,结果启动就报错。后来一查,Nextflow 从 21.04 版本开始要求 Java 11 以上。

验证一下你的环境:

java -version
# 应该看到 openjdk version "11.0.x" 或更高

如果没有,去 Adoptium 或者用包管理器装一个:

# Ubuntu / Debian
sudo apt update && sudo apt install openjdk-11-jdk

# CentOS / RHEL
sudo yum install java-11-openjdk

# macOS (Homebrew)
brew install openjdk@11

避坑提示:我曾经在某集群上同时装了 Java 8 和 Java 11,却忘了改 JAVA_HOME,导致 Nextflow 在后台任务里默认用了老版本。建议在 ~/.bashrc 里显式设置:
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

3.2 安装 Nextflow

安装方式有好几种,我推荐直接用 curl 一键脚本,最快。但如果你在无外网环境,conda 或手动下载也是常客。

  1. curl 安装(推荐)
curl -fsSL https://get.nextflow.io | bash
chmod +x nextflow
sudo mv nextflow /usr/local/bin/

完事后运行 nextflow -version,如果能打印出版本号,就说明成了。

  1. Conda / Mamba 安装
conda install -c bioconda nextflow
# 或者用更快的 mamba
mamba install -c bioconda nextflow

conda 会自动处理 Java 依赖,省事。不过 conda 环境的激活和切换有时会乱,我在生产流水线上宁可手动装。

  1. 手动下载二进制包
wget https://github.com/nextflow-io/nextflow/releases/download/v23.10.1/nextflow-23.10.1-all
chmod +x nextflow-23.10.1-all
./nextflow-23.10.1-all -version

这种方式适合离线环境,或者你需要在同一台机器上保留多个版本。

安装方式 优点 缺点
curl 一键脚本 简单、默认最新版 依赖网络,可能被墙
Conda 自动处理依赖 环境管理凌乱,版本滞后
手动下载 精确控制版本,离线友好 需要手动配置 PATH

3.3 版本管理

Nextflow 迭代很快。我见过有些团队用了半年没升级,结果新发布的管道(pipeline)要求 DSL2 新特性,但旧版本根本不支持。

怎么管理版本?三种常用做法:

  • 使用 nextflow self-update:自动更新到最新稳定版。简单粗暴,但不适合生产锁定。
  • 下载特定版本并重命名:例如 nextflow-23.10.1,需要哪个就把对应文件放在 PATH 下。
  • 用 nf-core 提供的 tools 管理:nf-core 的 --version 参数可以指定 Nextflow 版本,它会自动拉取对应版本运行。
# 查看当前版本
nextflow -version

# 更新到最新
nextflow self-update

# 使用特定版本运行(假设二进制文件已下载)
./nextflow-23.10.1 run hello

重要:不同管道对 Nextflow 版本有硬性要求。我在跑 nf-core/rnaseq 3.12 时,文档明确要求 ≥22.10。如果你用 21.04 去跑,会直接报错。建议每个项目都写一个 .nxf_version 文件并提交到 git 仓库。

3.4 DSL2 初体验

DSL2 是 Nextflow 的领域特定语言第二版。从 21.04 版本开始默认就是 DSL2 了。我不建议再学 DSL1,除非你要维护陈年旧项目。为什么?DSL2 让模块化变得很自然——你可以把不同处理步骤拆成独立的 module,复用性直接拉满。

最简单的 DSL2 工作流长这样:

// main.nf
nextflow.enable.dsl=2

process SAY_HELLO {
    input:
    val x

    output:
    path "result.txt"

    script:
    """
    echo "Hello $x!" > result.txt
    """
}

workflow {
    SAY_HELLO("World")
}

保存为 main.nf,然后运行:

nextflow run main.nf

看到 result.txt 里面写着 Hello World!,说明你的环境已经能跑 DSL2 了。注意 nextflow.enable.dsl=2 这一行——有些22.x的版本需要显式声明,但23+以后默认就是 DSL2。

特征 DSL1 DSL2
模块化 不支持模块导入 支持 include 和 module
进程定义 写在单一文件 可拆分到多个 .nf 文件
工作流入口 隐式入口 显式 workflow {}
兼容性 社区正在淘汰 所有新管道必用

我个人心得:第一次接触 DSL2 时,最不适应的是 workflow {} 这个块。你想想看,以前 DSL1 里你随便写个 process 然后直接 run 就行,现在必须显式声明入口。但这恰恰是审计追踪的关键——每个工作流的调用路径变得清晰可追踪。

3.5 配置环境:nextflow.config 与 profile

Nextflow 的配置系统很灵活,但也是新手容易踩坑的地方。一个 nextflow.config 文件可以控制执行器(local / slurm / AWS Batch)、资源限制(CPU、内存、容器镜像)、缓存目录等。

// nextflow.config
executor {
    name = 'local'
    queueSize = 4
}

process {
    container = 'nfcore/rnaseq:3.12'
    cpus = 4
    memory = '16 GB'
}

params {
    outdir = './results'
}

更实用的做法是用 profile 来区分不同环境。比如你在本地开发时用小资源,上生产就切到集群:

// nextflow.config
profiles {
    local {
        executor.name = 'local'
        process.cpus = 2
        process.memory = '4 GB'
    }
    cluster {
        executor.name = 'slurm'
        executor.queueSize = 100
        process.cpus = 8
        process.memory = '32 GB'
    }
}

运行的时候指定 profile:

nextflow run main.nf -profile local
# 或
nextflow run main.nf -profile cluster

我在管理多个项目时,会在项目根目录放一个 nextflow.config 专门放 params,再把执行器配置抽成 conf/ 子目录下的独立文件,然后用 includeConfig 'conf/local.config' 引用。这样不同人拉下来只需要改一个文件,不会互殴。

Nextflow 安装与配置知识结构 Java 11+ 依赖 curl 一键安装 conda 安装 手动二进制下载 版本管理 DSL2 入门 (process → workflow) 配置:config & profile 可重复 RNA-seq 分析环境就绪 审计追踪基础已搭建 关键:版本要锁定、配置要分 profile、DSL2 是未来方向 — 每个环节都可以落在 git 里,形成可审计的轨迹