3. 安装Cromwell(本地模式)

终于到了动手环节。

我记得第一次装Cromwell的时候,被一堆版本号和JVM参数搞得晕头转向。后来摸清套路才发现,核心就三件事:Java环境、下载JAR包、配个配置文件。下面我带你一步步走通。

3.1 环境准备:Java是绕不过的坎

Cromwell跑在JVM上,所以Java得先装好。你想想看,一个工作流引擎要是连Java都没有,就像瘸腿的战士。

最低版本要求:Java 11。我个人习惯装OpenJDK 11 LTS,稳定,社区也认。

用下面命令检查是否已有Java:

java -version

如果返回类似下面的信息,说明环境OK:

openjdk version "11.0.18" 2023-01-17 LTS
OpenJDK Runtime Environment (build 11.0.18+10-LTS)
OpenJDK 64-Bit Server VM (build 11.0.18+10-LTS, mixed mode)
我曾经踩过的坑: 直接用了系统自带的Java 8,结果Cromwell启动时抛出 UnsupportedClassVersionError,白忙活半小时。所以起步就把版本定牢。

如果没有Java,或者版本低于11,怎么装?

Ubuntu/Debian:

sudo apt update
sudo apt install openjdk-11-jdk -y

CentOS/RHEL:

sudo yum install java-11-openjdk-devel -y

macOS(Homebrew):

brew install openjdk@11

装完别忘了设 JAVA_HOME,许多工作流任务还指着它呢:

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
小提示: 可以把上面两行加到 ~/.bashrc 或 ~/.zshrc 里,这样每次终端启动就自动生效。我每次都这么干,省事。

3.2 下载Cromwell JAR包

装完Java,下一步就是拿到Cromwell本体。官方发布页在GitHub的Releases区,我们直接拉最新的稳定版。

我一般用 curl 下载,一行命令搞定:

curl -L -o cromwell-85.jar \
  https://github.com/broadinstitute/cromwell/releases/download/85/cromwell-85.jar

你想用 wget 也行:

wget -O cromwell-85.jar \
  https://github.com/broadinstitute/cromwell/releases/download/85/cromwell-85.jar

命令执行完后,你当前目录下应该有一个约200多MB的JAR文件。大小正常,别慌。

验证一下文件完整性:

ls -lh cromwell-85.jar

输出类似:

-rw-rw-r-- 1 user user 236M Mar 18 10:27 cromwell-85.jar
版本选择建议: 我一般挑最新的偶数版本号(如84、86),奇数版可能带实验性功能,生产环境不推荐。你如果刚入门,直接用我上面的85版就行。

3.3 本地模式配置文件

Cromwell默认启动会找 cromwell.conf,如果没有,它自己有一套默认值。但为了本地实战,我建议从最简单的配置开始。

新建一个文件 cromwell.local.conf,内容如下:

# 本地模式基础配置
backend.providers.Local.config.concurrent-job-limit = 4
backend.providers.Local.config.root = "cromwell-executions"
system.io.file-system-implementation = "nio"

这几行分别做了什么?我拆开给你看:

配置项 值 说明
concurrent-job-limit 4 同时跑几个任务。设成CPU核数差不多。我笔记本是4核,这数字刚好。
root "cromwell-executions" 运行时的输出目录,所有中间结果、日志、最终产出都放这里面。
file-system-implementation "nio" 文件系统实现,NIO性能比旧版好,也支持符号链接。
特别注意: 如果你电脑上已经有 cromwell-executions 这个目录,建议换个名字或清空它,否则旧的缓存可能会干扰新任务。我之前就是因为没清缓存,结果任务日志全是乱套的。

3.4 启动Cromwell服务

万事俱备,点一把火。

在JAR文件和配置文件同目录下执行:

java -jar cromwell-85.jar server \
  --config cromwell.local.conf

启动后你会看到控制台刷出一堆日志,最后出现类似这样的信息:

INFO  cromwell.system.SystemInitialization - Cromwell version 85 initialized
INFO  akka.http.impl.server.Server - Listening on http://0.0.0.0:8000

这表示Cromwell服务器已在本地8000端口跑起来了。

测试一下API通不通:

curl http://localhost:8000/engine/v1/status

返回:

{
  "status": "ok",
  "version": "85"
}
我个人习惯: 把这条curl命令存成 check-cromwell.sh,每次启动完就跑一下,看一眼状态,心里踏实。

3.5 第一个WDL任务验证

空跑没意思,我们传一个最简单的WDL上去,验证整个链路通不通。

创建一个文件 hello.wdl:

version 1.0

workflow hello_world {
  call hello_task
}

task hello_task {
  command {
    echo "Hello, Cromwell!"
  }
  output {
    String greeting = read_string(stdout())
  }
  runtime {
    docker: "ubuntu:latest"
  }
}

然后通过API提交:

curl -X POST "http://localhost:8000/api/workflows/v1" \
  -H "accept: application/json" \
  -F "workflowSource=@hello.wdl"

如果一切正常,返回的JSON里会包含一个 id 字段,类似:

{
  "id": "abcdef12-3456-7890-abcd-ef1234567890",
  "status": "Submitted"
}

等几秒后查一下结果:

curl "http://localhost:8000/api/workflows/v1/abcdef12-3456-7890-abcd-ef1234567890/status"

看到 "status": "Succeeded",恭喜你,本地模式跑通了。

避坑提醒: 如果是Windows或macOS,Docker不一定能直接用。你可以在 runtime 里去掉 docker 那一行,Cromwell就会用本地shell执行命令。不过这样一来环境隔离就没了,我建议还是装Docker好。

3.6 本地模式架构一览

现在你已经亲手把Cromwell跑起来了,脑子里应该有个全景图。下面这张SVG把本地模式的核心交互画出来了——从你发送WDL,到Cromwell调度后端进程,最后返回结果。

Cromwell本地模式架构流程 Cromwell本地模式 — 请求处理流程 用户 / 客户端 HTTP API端口8000 WDL工作流引擎 Local Backend 本地进程(Job) cromwell.local.conf 结果/日志回传

从上图能清楚看到:你提交的WDL先经过REST API,引擎解析工作流,本地后端负责调度进程,每个任务在独立子进程中跑。配置文件和JVM参数控制着并发数和输出位置。整个过程都在你一台机器上完成——这就是本地模式的价值:开发调试用,轻量又可控。

我的经验: 本地模式虽然简单,但你之后切换到云端时,很多概念是一样的——引擎还是那个引擎,只是后端从Local变成PAPI或AWS Batch。所以本地模式练好了,后面云端切换就顺水推舟。

3.7 本章小结

  • Java版本必须≥11,低了会报错。
  • 下载JAR包后,用 java -jar cromwell.jar server --config xxx.conf 启动。
  • 配置文件至少需要指定后端并发数和输出根目录。
  • 启动后可以用 curl 测试API状态。
  • 用简单的WDL任务验证整个链路的通断。

本地环境搭好了,后面章节我们才能安心折腾云端配置。嗯,先把这一步吃透,后面全是收获。