Dockerfile with .sh not working when running it inside Jenkins

I’m trying to run a shell script file inside a docker container. It’s working as expected when testing it with the command line but not when running it inside Jenkins (Windows Buildserver).

This is my Dockerfile:

FROM ubuntu:latest

RUN apt-get update \
 && apt-get dist-upgrade -y \
 && apt-get install -y \
    build-essential libgtest-dev \
 && apt-get clean

WORKDIR /src

COPY . .

#working when using CLI and Jenkinsfile
RUN echo "test" 

#working when using CLI and Jenkinsfile
RUN ls 

#working when using CLI but NOT with Jenkinsfile
RUN ./build.sh 

CMD ["./run_tests.sh"]

And this is how I run the dockerfile:

docker-build.sh

#!/bin/sh
set -x

#stop and rm old container if any
docker container stop build-fw
docker container rm build-fw

docker build -t build-fw .

docker run --name build-fw -d -it build-fw

docker logs build-fw

docker container stop build-fw
docker container rm build-fw

In Jenkins, I simply created a Freestyle project with the “Execute Shell” build step, where I simply ran the “docker-build.sh” script:

Execute Shell

./docker-build.sh

I got the following error output:

#12 0.586 /bin/sh: 1: ./build.sh: not found
#12 ERROR: executor failed running [/bin/sh -c ./build.sh]: exit code: 127
------
 > [8/8] RUN build.sh:
------
executor failed running [/bin/sh -c ./build.sh]: exit code: 127

The error in Jenkins states, that ./build.sh was not found, although RUN ls shows that build.sh exists.
However this works as expected when using CLI.

How can I fix this issue ?

That is probably not ./build.sh which is not found but you have an invalid character in the shell script. If you created the file on windows or pulled a repository from Git on Windows which changes line breaks, you can get an error message like this. Make sure the line endings are correct, linux compatible line endings. LF and not CR nor CRLF. In other words: \n and not \r nor \r\n.

Here is an example to reproduce the issue in a container:

docker run --rm -it bash
bash-5.1# printf '#!/bin/sh\r\n' > /build.sh
bash-5.1# ./build.sh
bash: ./build.sh: /bin/sh^M: bad interpreter: No such file or directory
bash-5.1# /bin/sh -c ./build.sh
/bin/sh: ./build.sh: not found
1 Like

Hello
its probably permission missing here is the updated Dockerfile,

FROM ubuntu:latest

RUN apt-get update \
 && apt-get dist-upgrade -y \
 && apt-get install -y \
    build-essential libgtest-dev \
 && apt-get clean

WORKDIR /src

COPY . .

#working when using CLI and Jenkinsfile
RUN echo "test" 

#working when using CLI and Jenkinsfile
RUN ls 
RUN chmod +x build.sh
#working when using CLI but NOT with Jenkinsfile
RUN ./build.sh 

CMD ["./run_tests.sh"]

Have you read my answer? Please, explain, why you think the issue was a permision issue which was clearly not the csse :slight_smile: . But I am curious about your point of view.

Although making sure the shell script is executable inside a Dockerfile was still a good advice.

in question it was mentioned that ls is showing file is available.

I tried reproducing the same with my sample build.sh file and it’s working after adding permission.

though actual or some sample build.sh file might give more insight.

for me it never works if I don’t give chmod permission.

Yes, and it existed, yet trying to run it showed “not found”, because “not found” was not actually related to the bash script itself, but the shebang line. This is why I created my example to reproduce the issue. If the shebang line is wrong, and you just run the script interactively from a terminal directly, that shebang line becomes the “interpreter” which in this case would be a “bad interpreter”. On the other hand if you run it as an argument of /bin/sh -c the shebang line will not be the interpreter, but /bin/sh itself in front of the script and it wants to execute every line unless it is emty or a comment. If the shebang line contains a carrige return characterit is interpreted as a command, but it is not a printable character so you will not see it in the error message only that it was “not found” as an executable command. Different shells could handle it differently, but this is how it worked in the alpine container then and I would be surprised if it would work differently today in most if the shell variants on Linux

The executable flag will not change in a container, so if the file was executable on the host, it is executable in the container for the same user (UID). If you create a shell script on the host without the executable flag or it only allows the owner toe xecute the script and you use user with different UID in the container, running chmod +x ./build.sh can allow everyone to execute it.