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

标签 docker synchronization wait docker-compose

根据Controlling startup order in Compose ,可以控制Docker Compose的顺序使用“wait-for-it”脚本启动容器。脚本 wait-for-it.sh需要 host:port 参数以及当端口可用时脚本应该执行的命令。文档建议 Docker Compose 使用 entrypoint: 选项调用此脚本。但是,如果使用此选项,容器将不再运行其默认的 ENTRYPOINTCMD,因为 entrypoint: 会覆盖默认值。

如何将这个默认命令提供给 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

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

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

一旦容器 liquibase 创建文件 /var/run/liquibase/donewait-for-file.sh 打印 Found文件 [/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,但是相反,它退出。为什么它没有按我的预期工作?

最佳答案

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

这是意料之中的,这就是 wait-for-it 的原因以 wrapper 脚本的形式呈现。
它确实允许执行“子命令”:

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.

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

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

这应该可以工作...除了 docker-compose issue 3140 (由 OP Derek Mahar 中的 the comments 提及)

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

那个问题suggests (2021 年 1 月)

If you have a custom image you can add a startscript to the build and call it inside the dockerfile and in the docker-compose you can call it again.
Thats a way to avoid duplicate for more complicated entrypoints.

关于docker - 如何让我的 Docker compose "wait-for-it"脚本调用原始容器 ENTRYPOINT 或 CMD?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37194733/

相关文章:

docker - 如何在Centos的生产环境中运行docker容器?

Docker 网络从默认网桥迁移

amazon-web-services - AWS ECS - 如何从 ECS 容器登录到 cloudwatch?

java - 这种锁定技术的名称是什么?

c - 我是否正确使用了 mutex_trylock?

java - 在 Java 中从 main() 中的 Thread 实例上运行 wait()

Docker中的Android开发环境

java - 现代 JVM 中的双重检查锁定

Java 等待特定间隔通知不起作用

java - 在 Jena 自定义 PropertyFunction 中等待服务器响应