【问题标题】:Daemonized buildbot start守护进程的 buildbot 启动
【发布时间】:2016-12-23 10:25:27
【问题描述】:

我正在尝试编写在 ENTRYPOINT/CMD Dockerfile 指令中运行 buildbot start 的最简单的 docker buildbot 主映像。
我尝试使用dumb-initgosuexec 的很多组合,但没有成功。
情况如下:

  1. 当我尝试使用命令 docker run -d -v $local/vol/bldbot/master:/var/lib/buildbot buildbot-master-test 运行 deamonized buildroot 时,容器成功启动,但它突然终止。日志如下:

    [时间戳] [-] 日志已打开。
    [时间戳] [-] twistd 16.0.0 (/usr/bin/python 2.7.12) 正在启动。
    [时间戳] [-] 反应器类:twisted.internet.epollreactor.EPollReactor。
    [时间戳] [-] 启动 BuildMaster -- buildbot.version: 0.9.2
    [时间戳] [-] 从“/var/lib/buildbot/master.cfg”加载配置
    [时间戳] [-] 使用 URL 'sqlite:/state.sqlite' 设置数据库
    [时间戳] [-] 将数据库日志模式设置为“wal”
    [时间戳] [-] 为 master 1 做家务 c8aa8b0d5ca3:/var/lib/buildbot
    [时间戳] [-] 添加 1 个新的变更源,删除 0
    [时间戳] [-] 添加 1 个新构建器,删除 0 个
    [时间戳] [-] 添加 2 个新调度程序,删除 0
    [时间戳] [-] 此主服务器上未配置 Web 服务器
    [时间戳] [-] 添加 1 个新工人,移除 0 个
    [时间戳] [-] PBServerFactory 从 9989 开始
    [时间戳] [-] 开始工厂
    [时间戳] [-] BuildMaster 正在运行

  2. 当我使用命令docker run --rm -it -v $local/vol/bldbot/master:/var/lib/buildbot buildbot-master-test /bin/sh 在交互模式下运行容器,然后运行命令buildbot start 时,一切都像魅力一样。

我已经研究过官方buildbot master docker镜像的内容,即buildbot/buildbot-master。我看到作者决定在start_buildbot.sh 中使用命令exec twistd -ny $B/buildbot.tac,而不是他们自己的buildbot start

所以问题是,如何在只运行buildbot start 的Dockerfile 中编写ENTRYPOINT/CMD 指令。


附录 1

Dockerfile内容

FROM        alpine:3.4

ENV BASE_DIR=/var/lib/buildbot SRC_DIR=/usr/src/buildbot
COPY start $SRC_DIR/
RUN \
    echo @testing http://nl.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories && \
    echo @community http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories && \
    apk add --no-cache \
        python \
        py-pip \
        py-twisted \
        py-cffi \
        py-cryptography@community \
        py-service_identity@community \
        py-sqlalchemy@community \
        gosu@testing \
        dumb-init@community \
        py-jinja2 \
        tar \
        curl && \
# install pip dependencies
    pip install --upgrade pip setuptools && \
    pip install "buildbot" && \
    rm -r /root/.cache

WORKDIR $BASE_DIR

RUN \
    adduser -D -s /bin/sh bldbotmaster && \
    chown bldbotmaster:bldbotmaster .

VOLUME $BASE_DIR

CMD ["dumb-init", "/usr/src/buildbot/start","buildbot","master"]

附录 2

start脚本内容

#!/bin/sh
set -e
BASE_DIR=/var/lib/buildbot

if [[ "$1" = 'buildbot' && "$2" = 'master' ]]; then

    if [ -z "$(ls -A "$BASE_DIR/master.cfg" 2> /dev/null)" ]; then
        gosu bldbotmaster buildbot create-master -r $BASE_DIR
        gosu bldbotmaster cp $BASE_DIR/master.cfg.sample $BASE_DIR/master.cfg
    fi

    exec gosu bldbotmaster buildbot start $BASE_DIR
fi

exec "$@"

【问题讨论】:

  • 您能否提供导致指定日志的 Dockerfile?
  • 感谢您的快速回复。你来了。
  • 你从主机复制到镜像的start脚本里面有什么?
  • 再次感谢。你来了。
  • 不带exec 或带CMD ["/usr/src/buildbot/start","buildbot","master"] 的变体产生相同的效果。

标签: linux docker dockerfile buildbot


【解决方案1】:

Buildbot 引导程序基于 Twisted 的“.tac”文件,预计将使用 twistd -y buildbot.tac 启动。 buildbot start 脚本实际上只是对 twistd 的便捷包装。它实际上只是运行 twistd,然后观察日志以确认 buildbot 成功启动。除了这个日志观察之外没有任何附加值,所以用 buildbot start 来启动 buildbot 并不是严格强制的。 你可以用twistd -y buildbot.tac开始它。

正如您所指出的,官方 docker 映像正在使用 twistd -ny buildbot.tac 启动 buildbot 如果你看一下 twistd 的帮助,-y 意味着 Twisted 守护进程将运行一个 .tac 文件,而 -n 意味着它不会守护进程。 这是因为 docker 自己在做进程监视,不希望它的入口点被守护。

buildbot start 命令还有一个--nodaemon 选项,它实际上只是“执行”到twistd -ny。 因此,对于您的 dockerfile,您也可以使用我们 twistd -nybuildbot start --nodaemon,这将是相同的。

另一个特定的 Docker 是 buildbot.tac 是不同的。它将twistd 日志配置为输出到stdout,而不是输出到twisted.log。 这是因为 docker 设计希望日志位于标准输出中,以便您可以独立于应用程序的技术配置任何精美的云日志转发器。

【讨论】:

    【解决方案2】:

    我再次研究了docker 参考和buildbot 手册并找到了一个提示。
    有一个ngnix例子的备注

    不要将service x start 命令传递给分离的容器。例如,此命令尝试启动 nginx 服务。

    $ docker run -d -p 80:80 my_image service nginx start

    这样就成功启动了容器内的nginx 服务。但是,它失败了分离容器范例,因为根进程 (service nginx start) 返回并且分离容器按设计停止。结果,nginx 服务已启动但无法使用。相反,要启动 nginx Web 服务器等进程,请执行以下操作:

    $ docker run -d -p 80:80 my_image nginx -g 'daemon off;'

    另一方面,有一个选项

    --nodaemon 选项指示 Buildbot 跳过守护进程。该过程将在前台开始。它只会在停止时返回命令行。

    以上两条路径都产生了

    exec gosu bldbotmaster buildbot start --nodaemon $BASE_DIR
    

    start 脚本行中至少解决了突然终止现象的行。

    【讨论】: