【问题标题】:Starting a service during Docker build在 Docker 构建期间启动服务
【发布时间】:2017-09-09 13:38:01
【问题描述】:

我想在 Docker 构建期间启动一项服务。在构建过程完成后,我不需要此服务继续运行(或者我知道我可以为此使用 CMD 命令),但是我确实需要它运行足够长的时间来执行依赖于此服务的第二个命令正在启动并运行。

更准确地说,我正在尝试为 ejabberd XMPP 服务器编写一个 Dockerfile,该服务器还为此服务器安装了一个模块。我正在尝试使用 ejabberdctl start 启动 ejabberd 服务器,然后使用 ejabberdctl module_install 实用程序安装模块,这取决于节点正在启动和运行。它看起来像这样:

RUN ejabberdctl start && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http

现在我遇到了一个问题,我想出了两个可能的原因。问题是我的构建从这一行开始不起作用,因为当第二个命令试图执行时节点已关闭。我收到以下错误,这是您尝试使用 ejabberdctl 实用程序时的典型错误,但节点实际上并未启动:

与节点 ejabberd@localhost 的 RPC 连接失败

命令 '/bin/sh -c ejabberdctl start && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http' 返回一个非零代码:3

这可能是因为服务的启动需要一点时间,比执行第二个命令所需的时间长,所以第二个命令运行到一个刚刚启动的节点。不确定这有多大可能。第二个原因可能是依赖于 init.d 的服务在构建过程中无法在 Docker 中启动。

我构建容器直到导致问题的那一行,进入容器并手动执行命令,一切正常。

总结一下,我想在构建过程中启动 ejabberd 服务器,然后使用它的控制工具安装一些东西。最后一个选项是在不运行服务器的情况下手动安装模块,但是我更喜欢使用 ejabberdctl 控制实用程序来安装。

【问题讨论】:

  • 您为什么不通过简单地添加睡眠来检验您的假设?即ejabberdctl start && sleep 10 && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http?
  • 您可以通过与ejabberdctl start 建立一行并查看它是否失败来测试第二个假设。
  • 第一个带有sleep 10 的版本成功了!模块安装成功,所以实际上是时间问题。有没有比使用睡眠更好的方法来解决这个问题?我看到了一些外部 shellscript 的解决方案,它在服务启动后运行并循环运行,直到它在进程列表中找到进程。不知道是不是有点多..

标签: docker dockerfile ejabberd docker-build


【解决方案1】:

这些*ctl 程序通常带有一些实用程序来启动/停止/监视服务的状态。

如果你的情况我认为最好的办法是有一个简单的 bash 脚本,你可以在构建时运行它:

  • 启动 ejabberd
  • 定期监控状态
  • 如果进程状态为 up,请运行您的命令

看看这个:

root@158479dec020:/# ejabberdctl 状态 与节点 ejabberd@158479dec020 的 RPC 连接失败:nodedown root@158479dec020:/# echo $? 3 root@158479dec020:/# ejabberdctl start root@158479dec020:/# echo $? 0 root@158479dec020:/# ejabberdctl 状态 节点 ejabberd@158479dec020 启动状态为:started ejabberd 16.01 正在该节点中运行 root@158479dec020:/# echo $? 0 root@158479dec020:/# ejabberdctl stop root@158479dec020:/# echo $? 0 root@158479dec020:/# ejabberdctl 状态 与节点 ejabberd@158479dec020 的 RPC 连接失败:nodedown root@158479dec020:/# echo $? 3

因此,这告诉我们,如果您运行 ejabberd status 并且守护程序未运行,您将收到退出代码 3,如果它已启动并运行,则 0

你的 bash 脚本就到这里了:

函数运行(){ ejabberdctl start # 重复以防万一... ejabberdctl 状态 &>/dev/null 如果 [ $? -当量0];然后 echo "在这里做点魔法,ejabberd 正在运行..." 出口 0 菲 echo "Ejabberd 还在下..." } 虽然是真的;跑;睡觉1;完毕

这就是你在 CLI 中得到的:

root@158479dec020:/# ./check.sh Ejabberd 还在下... 在这里做一些魔术,ejabberd 正在运行...... root@158479dec020:/# ejabberdctl stop root@158479dec020:/# ./check.sh Ejabberd 还在下... Ejabberd 还在下... 在这里做一些魔术,ejabberd 正在运行......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    相关资源
    最近更新 更多