如何让我的Docker撰写"wait-for-it"脚本来调用原始容器ENTRYPOINT或CMD?

Der*_*har 21 synchronization wait docker docker-compose

根据Compose中的Controlling启动顺序,可以通过使用" wait-for-it "脚本来控制Docker Compose启动容器的顺序.脚本需要一个参数以及脚本在端口可用时应该执行的命令.文档建议Docker Compose使用该选项调用此脚本.但是,如果使用此选项,容器将不再运行其默认值,或者因为覆盖默认值.wait-for-it.shhost:portentrypoint:ENTRYPOINTCMDentrypoint:

如何提供此默认命令wait-for-it.sh以便脚本可以调用默认值ENTRYPOINTCMD满足它等待的条件?

就我而言,我已经实现了一个wait-for-file.sh轮询等待文件存在的脚本:

#!/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
Run Code Online (Sandbox Code Playgroud)

Docker Compose调用wait-for-file.sh作为从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
Run Code Online (Sandbox Code Playgroud)

在成功退出之前,另一个自定义容器liquibase会创建/var/run/liquibase/done,因此platinum-oms有效地等待容器liquibase完成.

容器liquibase创建文件后/var/run/liquibase/done,wait-for-file.sh打印Found file [/var/run/liquibase/done].,但无法catalina.sh run在基本容器中调用默认命令tomcat:8-jre8.为什么?

测试场景

我创建了一个简化的测试场景docker-compose-wait-for-file来演示我的问题.容器ubuntu-wait-for-file等待容器ubuntu-create-file创建文件/wait/done,然后我希望容器ubuntu-wait-for-file调用默认的ubuntu容器命令/bin/bash,但它会退出.为什么它没有像我期望的那样工作?

Von*_*onC 8

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

这是预期的,这就是为什么它wait-for-it被呈现为包装脚本.
它确实允许执行"子命令":

wait-for-it.sh host:port [-s] [-t timeout] [-- command args]
                                               ^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

无论服务是否启动,子命令都将被执行.
如果只希望在服务启动时执行子命令,请添加--strict参数.

这意味着CMD图像的一部分可以用于实际的容器命令,因为它的参数将参数传递给ENTRYPOINT命令:

entrypoint: wait-for-it.sh host:port --
cmd: mycmd myargs
Run Code Online (Sandbox Code Playgroud)

这应该有效......除了docker-compose问题3140(OP Derek Mahar评论中提到)

在Dockerfile中定义的docker-compose.yml擦除中CMD定义的入口点