如何检测当前脚本是否在 Docker 构建中运行?

5
假设我有一个 Dockerfile 文件,其中运行了一个脚本。
RUN ./myscript.sh

我该如何编写 myscript.sh,以便在 docker build期间通过 RUN命令启动时能够检测到自身?
#! /bin/bash

# myscript.sh

if <What should I do here?>
then
  echo "I am in a docker build"
else
  echo "I am not in a docker build"
fi

理想情况下,它不应该需要对 Dockerfile 进行任何更改,这样调用 myscript.sh 的人就不需要对 myscript.sh 有专门的了解。

也许在调用脚本之前添加一个特定的资源,以便脚本可以检测到,或者带上一个参数调用脚本。否则我不确定这是否容易。 - boly38
如果你确定自己在一个镜像构建中,你会怎么做?为什么不能更改Dockerfile? - David Maze
例如,您正在维护一个安装脚本,该脚本可用于“docker build”或物理机器,并且您希望在安装脚本中包含一些特定于docker的优化。 - Yang Bo
3个回答

3

试试这个:

#!/bin/bash

# myscript.sh

isDocker(){
    local cgroup=/proc/1/cgroup
    test -f $cgroup && [[ "$(<$cgroup)" = *:cpuset:/docker/* ]]
}

isDockerBuildkit(){
    local cgroup=/proc/1/cgroup
    test -f $cgroup && [[ "$(<$cgroup)" = *:cpuset:/docker/buildkit/* ]]
}

isDockerContainer(){
    [ -e /.dockerenv ]
}

if isDockerBuildkit || (isDocker && ! isDockerContainer)
then
  echo "I am in a docker build"
else
  echo "I am not in a docker build"
fi

这大致上与如何确定进程是否在lxc / Docker内运行?相同的技巧; 但是,如果您在构建之外作为主容器命令运行docker run --rm the-image ./myscript.sh,它也会返回true吗? - David Maze
@DavidMaze 没错。我猜测 OP 想要区分 docker buildnon-docker build - Philippe
似乎在执行cat /proc/1/cgroup时,docker build和Docker容器之间存在差异。在docker build中,/proc/1/cgroup包含类似于/docker/buildkit/xxxxxxxxx的内容。而在Docker容器中,buildkit字符串不存在。 - Yang Bo
似乎 DOCKER_BUILDKIT=1DOCKER_BUILDKIT=0 会影响 cgroup - Yang Bo
确实,/proc/1/cgroup 包含 buildkit。 - Philippe
显示剩余4条评论

0

只是想参与此事,似乎我无法评论(也不能编辑,因为编辑只有两个字符,不足以在SO上进行),但它含有一个拼写错误的答案已被接受。

isDockerContainer 应该这样读

isDockerContainer(){
    [ -e /.dockerenv ]
}

这在我们的情况下创建了一个静默错误。

干杯


1
是的,我想说的是,由于声誉系统阻止了任何来自试图提供帮助的合法账户的互动,所以我唯一能够提供更正代码片段的方式就是通过这种方式。 - IceTDrinker

-4
在你的Dockerfile中,你可以尝试这样运行脚本。
ADD myscript.sh .

RUN chmod +x myscript.sh

ENTRYPOINT ["myscript.sh"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接