5

Suppose I have a Dockerfile which runs a script,

RUN ./myscript.sh

How could I write the myscript.sh so that it could detect if itself is launched by the RUN command during a docker build?

#! /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

Ideally, it should not require any changes in the Dockerfile, so that the caller of myscript.sh does not need specialized knowledge about myscript.sh.

Yang Bo
  • 3,586
  • 3
  • 22
  • 35
  • Maybe add a specific ressource before calling the script that the script could detect, or call the script with an argument. Else I'm not sure that's easy – boly38 Nov 05 '21 at 23:28
  • What would you do differently if you did determine you were in an image build? Why can't you change the Dockerfile? – David Maze Nov 05 '21 at 23:36
  • For example you are maintaining an installation script that could be used in either `docker build` or a physical machine, and you want to include some docker-specific optimization into the installation script. – Yang Bo Nov 06 '21 at 00:23

3 Answers3

3

Try this :

#!/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
Yang Bo
  • 3,586
  • 3
  • 22
  • 35
Philippe
  • 20,025
  • 2
  • 23
  • 32
  • This is approximately the same trick as [How to determine if a process runs inside lxc/Docker?](https://stackoverflow.com/questions/20010199/how-to-determine-if-a-process-runs-inside-lxc-docker); but won't it also return true if you `docker run --rm the-image ./myscript.sh` as the main container command outside a build? – David Maze Nov 05 '21 at 23:36
  • @DavidMaze You are right. I presume OP wanted to distinguish between `docker build` vs `non-docker build`. – Philippe Nov 05 '21 at 23:44
  • It seems there is a difference between `docker build` and a Docker container when executing `cat /proc/1/cgroup`. `/proc/1/cgroup` in a `docker build` contains something like `/docker/buildkit/xxxxxxxxx`. The `buildkit` string does not exist in a Docker container. – Yang Bo Nov 05 '21 at 23:50
  • @YangBo for me, /proc/1/cgroup is exactly the same in both cases. Also /.dockerenv exists in build phase. I tested debian image. Which image are you using ? – Philippe Nov 05 '21 at 23:53
  • It seems `DOCKER_BUILDKIT=1` or `DOCKER_BUILDKIT=0` affect the cgroup https://docs.docker.com/develop/develop-images/build_enhancements/ – Yang Bo Nov 05 '21 at 23:57
  • `.dockerenv` does not exist on buildkit – Yang Bo Nov 05 '21 at 23:57
  • Indeed, and /proc/1/cgroup contains buildkit. – Philippe Nov 05 '21 at 23:59
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238923/discussion-between-philippe-and-yang-bo). – Philippe Nov 06 '21 at 00:09
  • `/.dockerenv` no longer exists on never docker versions, so it's no longer working – Michael Kriese Aug 24 '23 at 08:01
0

Just to chime in on this, it seems I cannot comment (nor edit as the edit is two characters long... not enough for SO) on the accepted answer but it contains a typo.

the isDockerContainer should read

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

which created a silent bug in our case.

Cheers

IceTDrinker
  • 151
  • 5
  • 1
    Yes, all I’m saying is the only way I could provide the corrected snippet is through this mean because of the reputation system that prevents any interaction even from legitimate accounts who try to provide some help – IceTDrinker Feb 06 '22 at 09:24
-4

In your Dockerfile, you can try this to run the script

ADD myscript.sh .

RUN chmod +x myscript.sh

ENTRYPOINT ["myscript.sh"]