1. Nextflow 入门:安装、环境变量、hello world 示例
做计算药物发现的朋友应该都深有体会——管线里要串联几十个工具,从序列比对、分子对接,到机器学习预测,每一步都可能跑崩。我以前在团队里维护过一套用 Bash 脚本写的管线,那简直是噩梦:改一个工具参数要翻十几个脚本,并行调度?不好意思,靠自己写。后来接触到 Nextflow,说实话,就像从骑自行车直接换成了开高铁。今天我就带你亲手装好 Nextflow,跑通第一个 hello world,把基础踩实。
先来个全景图,让你直观看看我们这一章要搞定的四个大块:
为什么药物发现管线偏偏看上 Nextflow?
说白了,我们做药物发现的管线天生就是 “数据多、工具杂、依赖乱”。传统 Shell 脚本根本扛不住:
- 数据多:一个分子筛选项目,小则上千个化合物,大则百万级,需要自动分片并行。Nextflow 原生支持
channels和process的并行执行,开箱即用。 - 工具杂:Python、R、C++ 可执行、Docker/Singularity 容器——每个工具都有自己的环境。Nextflow 的
container指令让你彻底告别“在我机器上能跑”的尴尬。 - 依赖乱:同一个分析可能要用 Pandas 1.2 和 rdkit 2021.03,改了版本就报错。Nextflow 用容器打包编译环境,每个 process 隔离运行。
我的经验:以前做 ADMET 预测管线,40 多个步骤,后来换到 Nextflow,代码量直接砍半。最爽的是跑错一步自动重试,再也不用半夜爬起来看作业。
装好 JDK —— 地基打不牢,楼盖得再高也得塌
Nextflow 是个 Java 应用,所以第一件事就是把 JDK 装好。我个人习惯用 SDKMAN,它就像 Java 世界的 conda,切换版本特别方便。
使用 SDKMAN 安装 JDK(推荐)
# 安装 SDKMAN
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
# 安装 JDK 11(Nextflow 的最低要求)
sdk install java 11.0.20-tem
# 切换默认版本
sdk default java 11.0.20-tem
# 验证
java -version
如果不想用 SDKMAN,直接从 (此处不输出链接) 官网下载也行,但要手动设置 JAVA_HOME。记得加到 ~/.bashrc 或 ~/.zshrc 里:
export JAVA_HOME=/path/to/jdk-11.0.20
export PATH=$JAVA_HOME/bin:$PATH
小提示:我建议直接装 JDK 17,Nextflow 对 JDK 17 兼容性更好。新项目我都是用 JDK 17,没出过幺蛾子。
安装 Nextflow —— 两行命令的事
Nextflow 的安装本身极其简单,你甚至可以理解为下载一个 jar 包。官方提供了最方便的方式:
# 下载并安装到 ~/.local/bin/nextflow
curl -s https://get.nextflow.io | bash
# 如果你想把 nextflow 放到系统路径
mv nextflow ~/.local/bin/
# 或直接放到 /usr/local/bin/
sudo mv nextflow /usr/local/bin/
# 验证安装
nextflow -version
看到类似这样的输出,就说明成了:
N E X T F L O W
version 24.04.1 build 5902
created 12-04-2024 13:14 UTC (12:14 CEST)
cite doi:10.1038/nbt.3820
http://nextflow.io
需要注意的是,首次运行 Nextflow 时它会自动下载一些依赖,所以保证网络畅通。我记得在某个客户的内网环境里装,因为没配置代理,卡了半天。这里有个避坑:
⚠️ 我曾经被坑过:如果内网环境,务必设置 HTTP_PROXY 环境变量。另外,Nextflow 默认会向 nf-co.re 报告使用统计(nextflow.analytics),如果不放心,可以用 nextflow -disable-anon-stat 关闭。
环境变量配置 —— 让 Nextflow 知道该往哪干活
Nextflow 有几个环境变量很重要,配好了能省很多事。我列一个常用表:
| 环境变量 | 用途 | 建议设置值 |
|---|---|---|
NXF_HOME |
Nextflow 的配置、缓存和日志存储目录 | $HOME/.nextflow(默认)或自定义磁盘大的路径 |
NXF_WORK |
工作目录,存放中间文件 | 建议指向 SSD 或高速 NAS,如 /scratch/nxf_work |
NXF_OPTS |
JVM 启动参数 | -Xms1g -Xmx4g(根据内存调整) |
NXF_EXECUTOR |
默认执行器(local, sge, slurm 等) | 本地开发保持 local |
通常在 ~/.bashrc 末尾加上这几行,就能全局生效:
export NXF_HOME=$HOME/.nextflow
export NXF_WORK=/tmp/nxf_work
export NXF_OPTS="-Xms512m -Xmx4g"
为什么我特别强调 NXF_WORK 要设到高速分区?因为药物发现管线里很多中间文件特别大,比如分子对接的 .pdbqt 文件,一个就上兆,你要是放在家目录下的 HDD 上,I/O 会爆炸。我以前处理一个 10 万化合物的虚拟筛选,NXF_WORK 放在 SSD 上,整个任务快了 3 倍。
避坑指南:生产环境下,NXF_WORK 一定要配自动清理策略。Nextflow 不会自动删工作目录,跑完管线后得手动 rm -rf $NXF_WORK 或者写个 cron job。我曾经把服务器硬盘塞爆过,教训深刻。
Hello World 示例 —— 跑通第一个 Nextflow 管线
好,万事俱备,我们来写第一个 .nf 文件。新建 hello.nf,内容如下:
#!/usr/bin/env nextflow
// 定义一个进程:输出信息
process sayHello {
output:
path 'hello.txt'
script:
"""
echo "Hello from Nextflow!" > hello.txt
"""
}
// 定义工作流
workflow {
sayHello()
view("文件内容:")
def content = file('hello.txt').text
println(content)
}
用下面命令运行:
nextflow run hello.nf
正常会看到类似:
N E X T F L O W ~ version 24.04.1
Launching `hello.nf` [focused_poisson] DSL2 - revision: abcdef1234
executor > local (1)
[ab/cdefgh] process > sayHello (1) [100%] 1 of 1 ✔
文件内容:
Hello from Nextflow!
这个例子虽然简单,但已经包含了 Nextflow 最核心的两个概念:
- process:封装一个独立的计算单元,可以是一个命令、一个脚本、甚至一个容器。上面
sayHello就是一个 process。 - workflow:定义 process 之间的连接和数据流。第 2 行
workflow { ... }就是入口。 - channel:虽然上面没显式用,但其实
view()和file()背后就是数据流。后面我会专门讲。
想进阶一点?试试把 input 也加上,让 process 接收参数:
process greet {
input:
val name
output:
stdout
script:
"""
echo "Hello, \${name}!"
"""
}
workflow {
greet("Nextflow")
greet.view()
}
运行后输出:Hello, Nextflow!。这就为你后面的药物发现管线——把化合物名称或 SMILES 字符串传进 process——打好了基础。
小总结
这一章我们搞定了三件事:
- 安装了 JDK + Nextflow —— 两行命令 + 一个验证,门槛不高。
- 配好了关键环境变量 ——
NXF_HOME、NXF_WORK、NXF_OPTS是必选项,你加上去。 - 跑通了 hello world —— 理解了
process和workflow的基本用法。