第2章 环境搭建:安装Cromwell、MiniWDL以及配置运行环境
说实话,开始用WDL之前,最烦的就是环境配置。你想想看,工具链没搭好,连个“Hello World”都跑不起来,多打击信心。我刚开始接触时也栽过坑——Java版本不对、Python包冲突、配置文件写错……后来总结了一套步骤,按顺序来,基本十分钟就能搞定。
这一章我们搞定三样东西:Cromwell(工业级执行引擎)、MiniWDL(轻量级调试工具),以及本地运行环境的配置。我会把踩过的坑和习惯做法都告诉你。
2.1 安装Cromwell
Cromwell 是 Broad Institute 开发的 WDL 执行引擎,支持本地、集群、云等多种后端。我一般用它的 JAR 包,简单直接,不需要装乱七八糟的依赖。
依赖要求:Java 11 或更高版本。先确认下你有 Java 没:
java -version
如果版本低于11,去 https://adoptium.net 下载一个。我个人习惯用 AdoptOpenJDK 的 LTS 版本,稳定。
然后下载 Cromwell JAR:
wget https://github.com/broadinstitute/cromwell/releases/download/87/cromwell-87.jar
验证安装:
java -jar ~/tools/cromwell/cromwell-87.jar --version
如果看到版本号,就成功了。我在项目中遇到过因为 JDK 版本太高(比如 17 以上)导致某些老版 Cromwell 崩溃的情况,所以建议用 11 或 17,别追最新。
2.2 安装 MiniWDL
MiniWDL 是我个人最喜欢的调试工具。它是个 Python 库,轻量、单机执行,适合写 WDL 时快速验证逻辑。你想想看,如果每次调试都要整个 Cromwell 跑一遍,光启动时间就够喝杯咖啡了。
安装命令(建议在虚拟环境里装):
pip install miniwdl
如果遇到底层依赖问题(比如 lark-parser 版本冲突),加个 --upgrade 重装一遍就好。我之前在一台老 Ubuntu 机器上装的时候,报过 “Failed building wheel for lark-parser”,后来发现是 Python 3.6 太老了,升级到 3.8 就好了。
验证安装:
miniwdl --version
正常输出类似 miniwdl 1.9.1。
2.3 配置运行环境
环境不止是装两个工具,还要约定工作目录和输入输出路径。我通常用这样的目录结构:
my_pipeline/
├── workflows/ # 存放 .wdl 文件
├── inputs/ # 存放 .json 输入配置
├── outputs/ # 运行时生成的结果
└── configs/ # Cromwell 后端配置(如果用到)
Cromwell 默认的输出路径是当前目录下的 cromwell-executions,可以通过 -Dconfig.file 参数指定自定义配置文件来修改。MiniWDL 则默认在当前目录下生成 miniwdl_run/ 目录。
对于 Cromwell,我建议手写一个简单的配置文件 cromwell.conf,指定本地后端和输出目录:
include required(classpath("application"))
webservice {
port = 8000
}
backend {
default = "Local"
providers {
Local {
actor-factory = "cromwell.backend.impl.sfs.config.ConfigBackendLifecycleActorFactory"
config {
root = "outputs"
filesystems {
local {
localization = "copy-local"
}
}
}
}
}
}
这样跑 Cromwell 时加上 -Dconfig.file=configs/cromwell.conf 就能用自定义输出目录了。
2.4 验证环境:跑个 Hello World
光装完还不够,得跑一个最简单的 WDL 来验证三条链路:编写 → 校验 → 执行。
先写一个 hello.wdl:
version 1.0
workflow hello_workflow {
String name = "WDL"
call hello {
input:
name = name
}
}
task hello {
input {
String name
}
command {
echo "Hello, ~{name}!"
}
output {
String greeting = read_string(stdout())
}
}
再用 MiniWDL 快速验证语法和逻辑:
miniwdl run hello.wdl
应该看到类似输出:
Running workflow hello_workflow...
All outputs: ["Hello, WDL!"]
再用 Cromwell 跑一遍:
java -jar ~/tools/cromwell/cromwell-87.jar run hello.wdl
启动后它会打开一个 Web 服务(默认端口 8000),同时在本机执行任务。看到 “Run ID: xxxx” 就算成功。如果你嫌它开 Web 服务麻烦,加个参数 --no-curl 可以关掉。
2.5 工具对比与选型建议
我把两个工具的核心差异整理成了一张表,方便你根据场景选择:
| 特性 | Cromwell | MiniWDL |
|---|---|---|
| 运行模式 | 服务模式 + 命令行 | 纯命令行,单次运行 |
| 后端支持 | 本地、SLURM、AWS、GCP、PBS 等 | 仅本地(Docker 可选) |
| WDL 版本支持 | draft-2 / 1.0 / 1.1 | 1.0(部分 1.1) |
| 启动速度 | 较慢(依赖 Java 虚拟机启动) | 几乎瞬间 |
| 适用阶段 | 生产、大规模并行、集群运行 | 开发调试、本地原型验证 |
| 调试体验 | 有 Web UI 和 API,日志详细 | 命令行输出,轻量直接 |
2.6 整体环境关系图
下面这张图展示了我们在本章搭建的三大组件以及它们之间的关系。看不清?点图放大?不不,咱们直接看内嵌 SVG——
从上图可以看到,你的 WDL 源文件和输入配置可以同时交给两个引擎。Cromwell 偏向生产环境,MiniWDL 适合调试。两者都能调用本地 Shell 或 Docker 来实际执行命令,最后产出结果和日志。
2.7 常见问题与避坑指南
- Java 版本不对:Cromwell 启动时报 “UnsupportedClassVersionError”。我曾经被这个问题卡了半小时,后来发现用的 OpenJDK 8。换 JDK 11 就好了。
- MiniWDL 找不到命令:如果你把它装在虚拟环境里,记得先
source venv/bin/activate再跑。 - Cromwell 输出路径全是数字目录:那是因为没配
cromwell.conf,用默认的执行 ID 作为目录名。按我上面的配置文件改一下,输出结构就清爽了。 - WDL 语法校验不通过:先跑
miniwdl validate hello.wdl看看具体报错。MiniWDL 的错误信息比 Cromwell 更友好。