现在我们的Jenkins代理为每个Rails项目生成一个docker-compose.yml,然后运行docker-compose . docker-compose.yml有一个主“web”容器,里面有rbenv和我们所有其他Rails依赖项 . 它链接到包含测试Postgres DB的数据库容器 .
当我们需要实际运行测试并生成退出代码时,问题就出现了 . 我们的CI服务器仅在测试脚本返回出口0时才会部署,但即使其中一个容器命令失败,docker-compose也会返回0 .
另一个问题是DB容器无限期运行,即使在Web容器完成运行测试之后也是如此,因此 docker-compose up
永远不会返回 .
有没有办法在这个过程中使用docker-compose?我们需要能够运行容器,但在Web容器完成后退出并返回它的退出代码 . 现在,我们手动使用docker来启动数据库容器并使用--link选项运行Web容器 .
9 回答
从版本
1.12.0
开始,您可以使用--exit-code-from
选项 .来自documentation:
docker-compose run
是获取所需退出状态的简单方法 . 例如:或者,您可以选择inspect死容器 . 您可以使用
-f
标志来获取退出状态 .至于永远不会返回的db容器,如果你使用
docker-compose up
那么你将需要sigkill那个容器;这可能不是你想要的 . 相反,您可以使用docker-compose up -d
来运行守护进程的容器,并在测试完成时手动终止容器 .docker-compose run
应该为你运行链接的容器,但我听到有关一个错误的喋喋不休,因为它阻止了它现在按预期工作 .以kojiro的回答为基础:
docker-compose ps -q | xargs docker inspect -f '{{ .State.ExitCode }}' | grep -v '^0' | wc -l | tr -d ' '
获取容器ID
获取最后一次运行每个容器ID的退出代码
只有不以'0'开头的状态代码
计数非0状态代码的数量
修剪出白色空间
返回返回的非0退出代码的数量 . 如果所有内容都以代码0退出,则为0 .
使用
docker wait
获取退出代码:foo
是"project name" . 在上面的示例中,我明确指定了它,但是如果您没有't supply it, it' s目录名称 .bar
是您在docker-compose.yml中为待测系统提供的名称 .请注意,
docker logs -f
也是正确的,当容器停止时退出 . 所以你可以把在
docker-compose up
和docker wait
之间,您可以观看您的测试运行 .如果您愿意使用
docker-compose run
手动启动测试,奇怪的是,添加--rm
标志会使Compose准确反映您的命令的退出状态 .这是我的例子:
--exit-code-from SERVICE
和--abort-on-container-exit
在您需要运行所有容器以完成的情况下不起作用,但如果其中一个容器提前退出则会失败 . 例如,如果在不同的容器中同时运行2个测试套件 .使用@ spenthil的建议,您可以将
docker-compose
包装在一个脚本中,如果有任何容器,它将会失败 .然后在CI服务器上,只需将
docker-compose up
更改为./docker-compose.sh up
.docker-rails允许您指定将哪个容器的错误代码返回到主进程,因此CI服务器可以确定结果 . 对于带有docker的rails,CI和开发是一个很好的解决方案 .
例如
在
docker-rails.yml
中,由于命令docker-rails ci test
,将产生web
容器退出代码 .docker-rails.yml
只是标准docker-compose.yml
的元包装器,它为您提供了为不同环境继承/重用相同基本配置的潜力,即开发与测试对比parallel_tests .您可以看到存在状态:
如果您在一个docker引擎上运行具有相同名称的更多docker-compose服务,并且您不知道确切的名称:
echo %?
- 从test-chrome服务返回退出代码优点:
等待确切的服务退出
使用服务名称,而不是容器名称