执行 xvfb-运行 作为 docker 自定义命令

Execute xvfb-run as docker custom command

为什么 xvfb-运行 不会作为 docker 覆盖命令执行?

从这个 Dockerfile 中获取图像:

FROM ubuntu:20.04

RUN apt-get update && apt-get install -y xvfb

构建于:

docker build -f Dockerfile.xvfb -t xvfb-test 

如果我使用 xfvb-运行 执行自定义 docker 命令:

docker run xvfb-test bash -x /usr/bin/xvfb-run echo

卡住没完没了

但是,如果我进入图像 docker run --rm -it xvfb-test bash,并执行相同的命令 xvfb-运行 echo 它会立即完成(意味着 Xvfb服务器已启动并能够执行命令)

这是 xvfb-运行 脚本的摘录:

...
trap : USR1
(trap '' USR1; exec Xvfb ":$SERVERNUM" $XVFBARGS $LISTENTCP -auth $AUTHFILE >>"$ERRORFILE" 2>&1) &
XVFBPID=$!

wait || :
...

bash -x执行我们可以看到最后执行的行是什么:

+ XAUTHORITY=/tmp/xvfb-run.YwmHlq/Xauthority
+ xauth source -
+ trap : USR1
+ XVFBPID=16
+ wait
+ trap '' USR1
+ exec Xvfb :99 -screen 0 1280x1024x24 -nolisten tcp -auth /tmp/xvfb-run.YwmHlq/Xauthority

查看 xvfb-run 脚本及其卡住的地方似乎是信号 USR1 (Xvfb 进程发送)永远不会传播到 wait 语句。

强制信号传播的一种方法是将 --init 标志添加到 docker 运行 命令。 来自documentation,正是它的作用。

Run an init inside the container that forwards signals and reaps processes

由此

The docker --init option in the run command basically sets ENTRYPOINT to tini and passes the CMD to it or whatever you specify on the commandline. Without init, CMD becomes pid 1. In this case, /bin/bash

看起来 运行 没有初始化参数的命令,运行 作为 PID 1,没有正确处理信号 USR1。