85

I have a directory containing only two files, Dockerfile and sayhello.sh:

.
├── Dockerfile
└── sayhello.sh

The Dockerfile reads

FROM alpine
COPY sayhello.sh sayhello.sh
CMD ["sayhello.sh"]

and sayhello.sh contains simply

echo hello

The Dockerfile builds successfully:

kurtpeek@Sophiemaries-MacBook-Pro ~/d/s/trybash> docker build --tag trybash .
Sending build context to Docker daemon 3.072 kB
Step 1/3 : FROM alpine
 ---> 665ffb03bfae
Step 2/3 : COPY sayhello.sh sayhello.sh
 ---> Using cache
 ---> fe41f2497715
Step 3/3 : CMD sayhello.sh
 ---> Using cache
 ---> dfcc26c78541
Successfully built dfcc26c78541

However, if I try to run it I get an executable file not found in $PATH error:

kurtpeek@Sophiemaries-MacBook-Pro ~/d/s/trybash> docker run trybash
container_linux.go:247: starting container process caused "exec: \"sayhello.sh\": executable file not found in $PATH"
docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "exec: \"sayhello.sh\": executable file not found in $PATH".
ERRO[0001] error getting events from daemon: net/http: request canceled

What is causing this? I recall running scripts in debian:jessie-based images in a similar manner. So perhaps it is Alpine-specific?

0

4 Answers 4

141

Alpine comes with ash as the default shell instead of bash.

So you can

  1. Have a shebang defining /bin/bash as the first line of your sayhello.sh, so your file sayhello.sh will begin with bin/sh

    #!/bin/sh
    
  2. Install Bash in your Alpine image, as you seem to expect Bash is present, with such a line in your Dockerfile:

    RUN apk add --no-cache --upgrade bash
    
Sign up to request clarification or add additional context in comments.

3 Comments

Changing CMD ["sayhello.sh"] to CMD ["./sayhello.sh"] in Dockerfile solved the problem for me, without the need for installing Bash.
I needed to add #!/bin/ash to the top of the script to have it interpreted correctly
The point 1. says "Have a shebang defining /bin/bash as the first line of your sayhello.sh," should that be "defining /bin/sh" ?
44

This answer is completely right and works fine.

There is another way. You can run a Bash script in an Alpine-based Docker container.

You need to change CMD like below:

CMD ["sh", "sayhello.sh"]

And this works too.

2 Comments

Though this may work bash scripts are not 100% API compatible with sh scripts. sh I believe stands for shell where as Bash stands for Bourne Again SHell. gnu.org/software/bash/manual/html_node/… So just so future visitors know they really are different shells.
The question is explicitly looking for a way to run "bash", not "sh". Just saying run the bash script using sh is not an answer - it's an anti-answer! What if that script has a command unique to bash?
12

Remember to grant execution permission for all scripts.

FROM alpine
COPY sayhello.sh /sayhello.sh
RUN chmod +x /sayhello.sh
CMD ["/sayhello.sh"]

3 Comments

grant execution permission is not required in Dockerfile if it has permission already
Excuse my boldness in asking you a question, because when I terminate my Dockerfile that way, and I have run it with docker-compose up -d, I can't access the bash, while with other containers like php, nginx that terminate with CMD, I can access the bash.
@jcarlosweb because Alpine ships no bash, only ash
5

By using the CMD, Docker is searching the sayhello.sh file in the PATH, BUT you copied it in / which is not in the PATH.

So use an absolute path to the script you want to execute:

CMD ["/sayhello.sh"]

BTW, as @user2915097 said, be careful that Alpine doesn't have Bash by default in case of your script using it in the shebang.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.