如何在 Alpine Docker 容器中运行 Bash 脚本?

Posted

技术标签:

【中文标题】如何在 Alpine Docker 容器中运行 Bash 脚本?【英文标题】:How do I run a Bash script in an Alpine Docker container? 【发布时间】:2017-12-01 21:45:16 【问题描述】:

我的目录只包含两个文件,Dockerfilesayhello.sh

.
├── Dockerfile
└── sayhello.sh

Dockerfile 读取

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

sayhello.sh 包含简单

echo hello

Dockerfile 构建成功:

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

但是,如果我尝试 run 它,我会收到 executable file not found in $PATH 错误:

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

这是什么原因造成的?我记得以类似的方式在基于debian:jessie 的图像中运行脚本。所以也许它是 Alpine 特有的?

【问题讨论】:

【参考方案1】:

Alpine 附带 ash 作为默认 shell,而不是 bash

所以你可以

    有一个定义 /bin/bash 作为 sayhello.sh 的第一行的 shebang,所以你的文件 sayhello.sh 将以 bin/sh 开头

    #!/bin/sh
    

    在你的 Alpine 镜像中安装 Bash,正如你所期望的那样,Bash 存在,在你的 Dockerfile 中有这样一行:

    RUN apk add --no-cache --upgrade bash
    

【讨论】:

在 Dockerfile 中将 CMD ["sayhello.sh"] 更改为 CMD ["./sayhello.sh"] 为我解决了这个问题,而无需安装 Bash。 我需要在脚本顶部添加#!/bin/ash 才能正确解释它【参考方案2】:

This answer 完全正确,工作正常。

还有另一种方法。您可以在基于 Alpine 的 Docker 容器中运行 Bash 脚本。

您需要像下面这样更改 CMD:

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

这也有效。

【讨论】:

虽然这可能有效,但 bash 脚本并非 100% API 与 sh 脚本兼容。 sh 我相信代表 shell,而 Bash 代表 Bourne Again SHell。 gnu.org/software/bash/manual/html_node/… 所以未来的访客知道他们真的是不同的贝壳。【参考方案3】:

记得授予所有脚本的执行权限。

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

【讨论】:

已有权限的Dockerfile不需要授予执行权限 请原谅我冒昧地问你一个问题,因为当我以这种方式终止我的 Dockerfile 并且我使用 docker-compose up -d 运行它时,我无法访问 bash,而使用其他容器就像以CMD 结尾的php, nginx,我可以访问bash @jcarlosweb 因为 Alpine 没有 bash,只有 ash【参考方案4】:

通过使用CMD,Docker 正在搜索PATH 中的sayhello.sh 文件,但是您将其复制到/ 中,而PATH 中没有。

所以使用你要执行的脚本的绝对路径:

CMD ["/sayhello.sh"]

顺便说一句,正如@user2915097 所说,请注意 Alpine 默认情况下没有 Bash,以防您的脚本在 shebang 中使用它。

【讨论】:

以上是关于如何在 Alpine Docker 容器中运行 Bash 脚本?的主要内容,如果未能解决你的问题,请参考以下文章

无法在基于 Alpine 的 Docker 容器中运行 Play 框架应用程序

如何让 /etc/profile 在 Alpine / Docker 中自动运行

在 Alpine Docker 容器中运行 OpenSSH

如何在 docker 容器中运行 grails-vue 配置文件?

无法使用 node:alpine 在 Docker 容器中运行 React 应用程序的开发版本

如何在alpine:3.6 Docker容器中指定静态(非DHCP)DNS?