How to run a bash script in an Alpine Docker conta

2019-02-08 07:28发布

问题:

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 

Can someone explain what is causing this? (I recall running scripts in debian:jessie-based images in a similar manner, so perhaps it is Alpine-specific)?

回答1:

Alpine comes with /bin/sh as default shell instead of /bin/bash

So you can

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

#!/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 --update bash && rm -rf /var/cache/apk/*



回答2:

This answer is completely right and works fine.

There is another way, you can run bash script in alpine based docker

You need to change CMD like bellow

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

And this works too.



回答3:

Remember to grant execution permission for all scripts.

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


回答4:

By using the CMD, docker is searching the sayhello.sh in the PATH, BUT you copied it in / wich is not in the PATH.

So use 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.