首页 > 解决方案 > 运行 Docker,执行命令,退出

问题描述

作为构建过程的一部分,我正在尝试在 docker 中运行测试。我想做的是启动 docker 容器,忽略正常的入口点,运行测试命令,然后立即以测试状态退出。

就像是:

results=`docker run my_image --entrypoint python -m unittest discover`

当我尝试这个时,我得到:entrypoint requires the handler name to be the first argument

到目前为止,我只看到每个选项 A)启动容器并发出任意命令,或 B)有第二个 Dockerfile 仅用于测试。

是否可以使用任意命令(忽略默认入口点)运行 docker 映像,在执行命令后容器被杀死?

标签: docker

解决方案


理想情况下,您应该重组应用程序以避免需要覆盖入口点。

请记住,当您运行图像时,ENTRYPOINT组合CMD成一个命令。如果您将经常替换此(组合)命令字符串,最好将整个命令放入CMD. 如果ENTRYPOINT有的话,它应该是一个包装器,运行作为参数传递给它的命令(在 shell 脚本中,带有exec "$@")。

# Optional entrypoint -- MUST be JSON-array syntax, and MUST `exec "$@"`
# ENTRYPOINT ["/entrypoint.sh"]
CMD python ... whatever you had before

然后一旦你这样做,你可以很容易地覆盖命令中的命令docker run部分

docker run my_image python -m unittest discover

ENTRYPOINT(我还见过另外两种模式。一种是“容器即命令”模式,其中整个命令行在 中ENTRYPOINT,命令部分用于获取附加参数;这支持一种docker run imagename --extra-args模式。如果你真的需要这个模式,请参见下文以覆盖整个内容。第二个任意拆分ENTRYPOINT ["python"], CMD ["script.py"],但没有特别的理由这样做;只需将它们组合成CMD.)

如果你不能重构你的镜像的 Dockerfile,那么你需要覆盖--entrypoint. 但是,此选项只需要一个命令字,并且它被视为 Docker 选项,因此它需要位于映像名称之前。这导致了这种尴尬的结构(为了便于阅读,分成多行):

docker run \
  --entrypoint python \
  my_image \
  -m unittest discover

还要考虑将非 Docker 主机虚拟环境用于运行服务的单元测试等日常任务的可能性。


推荐阅读