How do I run a Bash script in an Alpine Docker container?

DockerDockerfileAlpine

Docker Problem Overview


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?

Docker Solutions


Solution 1 - Docker

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
    

Solution 2 - Docker

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.

Solution 3 - Docker

Remember to grant execution permission for all scripts.

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

Solution 4 - Docker

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKurt PeekView Question on Stackoverflow
Solution 1 - Dockeruser2915097View Answer on Stackoverflow
Solution 2 - DockerShahriarView Answer on Stackoverflow
Solution 3 - DockerdebusView Answer on Stackoverflow
Solution 4 - DockerzigarnView Answer on Stackoverflow