我如何使我的Docker组成“等待它”脚本调用原始容器ENTRYPOINT或CMD? [英] How can I make my Docker compose "wait-for-it" script invoke the original container ENTRYPOINT or CMD?

查看:195
本文介绍了我如何使我的Docker组成“等待它”脚本调用原始容器ENTRYPOINT或CMD?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据控制撰写中的启动顺序,可以控制 Docker Compose 通过使用等待它脚本。脚本 wait-for-it.sh 需要一个 host:port 参数以及脚本在端口可用时执行的命令。该文档建议Docker Compose使用 entrypoint:选项来调用此脚本。但是,如果使用此选项,容器将不再运行其默认的 ENTRYPOINT CMD ,因为 entrypoint:覆盖默认值。



如何将这个默认命令提供给等待它。 sh ,以便脚本可以调用默认的 ENTRYPOINT CMD 它等待满足?



在我的情况下,我已经实现了一个脚本 wait-for-file.sh 等待文件存在的投票:

 #!/ bin / bash 

set -e

waitFile =$ 1
shift
cmd =$ @

直到test -e $ waitFile
do
>& 2 echo等待文件[$ waitFile]。
sleep 1
done

>& 2 echo找到的文件[$ waitFile]。
exec $ cmd

Docker Compose调用等待文件.sh 作为从 tomcat:8-jre8

  oms:
image:opes / platinum-oms
ports:
- 8080:8080
volumes_from:
- liquibase
links:
- postgres:postgres
- activemq:activemq
depends_on:
- liquibase
- activemq
entrypoint:/wait-for-file.sh / var / run /在其成功退出之前,另一个自定义容器 liquibase
$ b $ p
$ b

c $ c>创建 / var / run / liquibase / done ,因此 platinum-oms 有效地等待容器 liquibase 完成。



一旦容器 liquibase c reates file / var / run / liquibase / done wait-for-file.sh 打印找到文件[/ var / run / liquibase / done]。,但无法调用默认命令catalina.sh运行 在基础容器中 tomcat:8-jre8 。为什么?



测试场景



我创建了一个简化的测试场景 docker-compose-wait-for-file 来演示我的问题。容器 ubuntu-wait-for-file 等待容器 ubuntu-create-file 创建文件 / wait / done 然后我希望容器 ubuntu-wait-for-file 调用默认的 ubuntu 容器命令 / bin / bash ,而是退出。为什么不按照我的期望工作?

解决方案


但是,如果使用此选项,容器将不再运行其默认的 ENTRYPOINT CMD 命令,因为 entrypoint:覆盖默认值。


这是预期的,这就是为什么 wait-for-it 被显示为包装器脚本。

它允许执行子命令:

 等待.sh host:port [-s] [-t timeout] [ -  command args] 
^^^^^^^^^^^




子命令将被执行,无论服务是否启动。

如果要执行子命令只要服务已经启动,请添加 - strict 参数。


这意味着您的图像的 CMD 部分可以用于您的实际容器命令,因为其参数将通过参数传递到 ENTRYPOINT 命令:

  entrypoint:wait-for-it.sh host:port  -  
cmd:mycmd myargs

这应该工作...除了 docker-compose issue 3140 (由OP Derek Mahar 评论


docker-compose.yml中定义的entrypoint 擦除在Dockerfile

中定义的 CMD


According to Controlling startup order in Compose, one can control the order in which Docker Compose starts containers by using a "wait-for-it" script. Script wait-for-it.sh expects both a host:port argument as well as the command that the script should execute when the port is available. The documentation recommends that Docker Compose invoke this script using the entrypoint: option. However, if one uses this option, the container will no longer run its default ENTRYPOINT or CMD because entrypoint: overrides the default.

How might one provide this default command to wait-for-it.sh so that the script can invoke the default ENTRYPOINT or CMD when the condition for which it waits is satisfied?

In my case, I've implemented a script wait-for-file.sh that polls waiting for a file to exist:

#!/bin/bash

set -e

waitFile="$1"
shift
cmd="$@"

until test -e $waitFile
do
  >&2 echo "Waiting for file [$waitFile]."
  sleep 1
done

>&2 echo "Found file [$waitFile]."
exec $cmd

Docker Compose invokes wait-for-file.sh as the entry-point to a slightly custom container derived from tomcat:8-jre8:

  platinum-oms:
    image: opes/platinum-oms
    ports:
      - "8080:8080"
    volumes_from:
      - liquibase
    links:
      - postgres:postgres
      - activemq:activemq
    depends_on:
      - liquibase
      - activemq
    entrypoint: /wait-for-file.sh /var/run/liquibase/done

Before it exits successfully, another custom container liquibase creates /var/run/liquibase/done and so platinum-oms effectively waits for container liquibase to complete.

Once container liquibase creates file /var/run/liquibase/done, wait-for-file.sh prints Found file [/var/run/liquibase/done]., but fails to invoke default command catalina.sh run in base container tomcat:8-jre8. Why?

Test Scenario

I created a simplified test scenario docker-compose-wait-for-file to demonstrate my problem. Container ubuntu-wait-for-file waits for container ubuntu-create-file to create file /wait/done and then I expect container ubuntu-wait-for-file to invoke the default ubuntu container command /bin/bash, but instead, it exits. Why doesn't it work as I expect?

解决方案

However, if one uses this option, the container will no longer run its default ENTRYPOINT or CMD command because entrypoint: overrides the default.

That is expected, which is why the wait-for-it is presented as a wrapper script.
It does allow to execute a "subcommand" though:

wait-for-it.sh host:port [-s] [-t timeout] [-- command args]
                                               ^^^^^^^^^^^^

The subcommand will be executed regardless if the service is up or not.
If you wish to execute the subcommand only if the service is up, add the --strict argument.

That means the CMD part of your image can be used for your actual container command, as its parameters will passed in parameters to the ENTRYPOINT command:

entrypoint: wait-for-it.sh host:port --
cmd: mycmd myargs

This should work... except for docker-compose issue 3140 (mentioned by the OP Derek Mahar in the comments)

entrypoint defined in docker-compose.yml wipes out CMD defined in Dockerfile

这篇关于我如何使我的Docker组成“等待它”脚本调用原始容器ENTRYPOINT或CMD?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆