问题
我如何在Docker容器内运行工具?
目标
了解如何在完全受控的运行时中调用工具。
Docker容器为软件及其依赖提供了一个完整的运行环境,从而简化了软件安装。然而,容器也被有意地与主机系统隔离,因此为了在Docker容器中运行工具,需要额外的工作来确保输入文件在容器中可用,输出文件可以从容器中恢复。CWL运行器可以自动执行这项工作,允许你使用Docker来简化你的软件管理,同时避免调用和管理Docker容器的复杂性。
CWL运行器的职责之一是调整输入文件的路径,以反映它们在容器中出现的位置。
这个例子在Docker容器中运行一个简单的Node.js脚本,然后将” Hello World “打印到标准输出。
docker.cwl
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool
baseCommand: node
hints:
DockerRequirement:
dockerPull: node:slim
inputs:
src:
type: File
inputBinding:
position: 1
outputs:
example_out:
type: stdout
stdout: output.txt
docker-job.yml
src:
class: File
path: hello.js
在我们运行它之前,让我们先把它分解一下,看看其中一些能做什么。大部分内容已经在前面的章节中解释过了,唯一的新部分是dockerRequirement部分。
baseCommand: node
hints:
DockerRequirement:
dockerPull: node:slim
baseCommand:node告诉CWL我们将在一个容器中运行这个命令。然后,我们需要为如何找到我们想要的容器指定一些hints。在这个例子中,我们只在DockerRequirements中列出了我们对docker容器的要求。dockerPull:参数的值与你运行docker pull命令的参数值相同。也就是说,容器映像的名称(您甚至可以指定标记,在使用容器进行可重现性研究时,这是最佳实践的好主意)。在本例中,我们使用了名为node:slim的容器。
$ echo "console.log(\"Hello World\");" > hello.js
$ cwl-runner docker.cwl docker-job.yml
[job docker.cwl] /tmp/tmpgugLND$ docker \
run \
-i \
--volume=/tmp/tmpgugLND:/var/spool/cwl:rw \
--volume=/tmp/tmpSs5JoN:/tmp:rw \
--volume=/home/me/cwl/user_guide/hello.js:/var/lib/cwl/job369354770_examples/hello.js:ro \
--workdir=/var/spool/cwl \
--read-only=true \
--user=1000 \
--rm \
--env=TMPDIR=/tmp \
--env=HOME=/var/spool/cwl \
node:slim \
node \
/var/lib/cwl/job369354770_examples/hello.js > /tmp/tmpgugLND/output.txt
[job docker.cwl] completed success
{
"example_out": {
"location": "file:///home/me/cwl/user_guide/output.txt",
"basename": "output.txt",
"class": "File",
"checksum": "sha1$648a6a6ffffdaa0badb23b8baf90b6168dd16b3a",
"size": 12,
"path": "/home/me/cwl/user_guide/output.txt"
}
}
Final process status is success
$ cat output.txt
Hello World
注意,CWL运行器构造了一个Docker命令行来运行脚本。
在这个例子中,hello.js脚本的路径在容器外部是/home/me/cwl/user_guide/hello.js,而在容器内部是/var/lib/cwl/job369354770_examples/hello.js,这在node命令的调用中得到了反映。