我有一个安装 grunt
的 docker 映像,但是当我尝试运行它时,出现错误:
Error response from daemon: Cannot start container foo_1: \
exec: "grunt serve": executable file not found in $PATH
如果我在交互模式下运行 bash,则 grunt
可用。
我究竟做错了什么?
这是我的 Dockerfile:
# https://registry.hub.docker.com/u/dockerfile/nodejs/ (builds on ubuntu:14.04)
FROM dockerfile/nodejs
MAINTAINER My Name, me@email.com
ENV HOME /home/web
WORKDIR /home/web/site
RUN useradd web -d /home/web -s /bin/bash -m
RUN npm install -g grunt-cli
RUN npm install -g bower
RUN chown -R web:web /home/web
USER web
RUN git clone https://github.com/repo/site /home/web/site
RUN npm install
RUN bower install --config.interactive=false --allow-root
ENV NODE_ENV development
# Port 9000 for server
# Port 35729 for livereload
EXPOSE 9000 35729
CMD ["grunt"]
CMD grunt
构建 docker 吗?或者您可以尝试通过传递完整路径来执行 grunt 命令?
CMD grunt?
重新构建您的意思是删除 ["
和 "]
吗?
CMD ["grunt"]
更改为 CMD grunt
CMD ["grunt"]
,您将使用另一个 shell 来执行命令,因此在该 shell 中可能不会设置 $PATH。
这是我粘贴错误消息时谷歌上的第一个结果,这是因为我的论点有问题。
容器名称必须在所有参数之后。
坏的:
docker run <container_name> -v $(pwd):/src -it
好的:
docker run -v $(pwd):/src -it <container_name>
当您对命令使用 exec 格式时(例如,CMD ["grunt"]
,一个带双引号的 JSON 数组),它将在 没有 shell 的情况下执行。这意味着大多数环境变量将不存在。
如果您将命令指定为常规字符串(例如 CMD grunt
),则 CMD
之后的字符串将与 /bin/sh -c
一起执行。
Dockerfile reference 的 CMD 部分提供了有关这方面的更多信息。
sudo set
或 (exec set)
。这些将失败,因为它们在没有 shell 的情况下执行命令(并且 set
是内置的 shell)。但是,sudo ls
和 (exec ls)
将起作用,因为 ls
是实际的二进制文件 /bin/ls
。
我发现了同样的问题。我做了以下事情:
docker run -ti devops -v /tmp:/tmp /bin/bash
当我将其更改为
docker run -ti -v /tmp:/tmp devops /bin/bash
它工作正常。
-v
的用法。 -v
是绑定挂载一个卷(如docker run --help | grep "\-v"
中所述),对我来说,我已经在File Sharing
(Docker设置)中挂载了/tmp
,为什么还要再次使用它呢?
像这样的错误有几个可能的原因。
在我的情况下,这是由于可执行文件(来自 Ghost blog Dockerfile 的 docker-entrypoint.sh
)在我下载后缺少可执行文件模式。
解决方案:chmod +x docker-entrypoint.sh
出于某种原因,除非我添加“bash”澄清器,否则我会收到该错误。即使在我的入口点文件顶部添加“#!/bin/bash”也无济于事。
ENTRYPOINT [ "bash", "entrypoint.sh" ]
COPY
,然后是 RUN chmod +x /compile_nibbler.sh
。
ENTRYPOINT [ "sh", "entrypoint.sh" ]
一个 Docker 容器可以在没有外壳的情况下构建(例如 https://github.com/fluent/fluent-bit-docker-image/issues/19)。
在这种情况下,您可以复制一个静态编译的 shell 并执行它,例如
docker create --name temp-busybox busybox:1.31.0
docker cp temp-busybox:/bin/busybox busybox
docker cp busybox mycontainerid:/busybox
docker exec -it mycontainerid /bin/busybox sh
我有同样的问题,经过大量的谷歌搜索,我无法找到如何解决它。
突然我注意到我的愚蠢错误:)
As mentioned in the docs,docker run
的最后一部分是加载容器后要运行的命令及其参数。
不是容器名称!!!
那是我尴尬的错误。
下面我为您提供了我的命令行图片,以查看我做错了什么。
这就是 docs 中提到的修复。
https://i.stack.imgur.com/uNQQ2.jpg
在显示的错误消息中:
来自守护程序的错误响应:无法启动容器 foo_1:\ exec:“grunt serve”:$PATH 中找不到可执行文件
它抱怨它找不到可执行文件 grunt serve
,而不是它找不到带有参数 serve
的可执行文件 grunt
。对该特定错误最可能的解释是使用 json 语法运行命令:
[ "grunt serve" ]
在您的撰写文件中。这是无效的,因为 json 语法要求您拆分每个参数,这些参数通常会由 shell 在每个空间上为您拆分。例如:
[ "grunt", "serve" ]
您可以将这两者都放入单个参数的另一种可能方法是,如果您要在 docker run
命令中将它们引用到单个 arg 中,例如
docker run your_image_name "grunt serve"
在这种情况下,您需要删除引号,以便将其作为单独的参数传递给运行命令:
docker run your_image_name grunt serve
对于看到这一点的其他人,executable file not found
意味着 Linux 看不到您尝试在容器中运行的具有默认 $PATH
值的二进制文件。这可能意味着很多可能的原因,这里有一些:
您还记得在图像中包含二进制文件吗?如果您运行多阶段映像,请确保在最后阶段运行二进制安装。使用交互式 shell 运行您的图像并验证它是否存在: docker run -it --rm your_image_name /bin/sh
您在进入容器时的路径可能会针对交互式 shell 进行修改,特别是如果您使用 bash,因此您可能需要指定容器内二进制文件的完整路径,或者您可能需要使用以下命令更新 Dockerfile 中的路径: ENV PATH=$PATH:/custom/dir/bin
二进制文件可能没有设置执行位,因此您可能需要使其可执行。使用 chmod 执行此操作: RUN chmod 755 /custom/dir/bin/executable
二进制文件可能包含映像中不存在的动态链接库。您可以使用 ldd 查看动态链接库的列表。一个常见的原因是使用 glibc(大多数 Linux 环境)编译并使用 musl(由 Alpine 提供)运行:ldd /path/to/executable
如果您使用卷运行映像,则该卷可以覆盖映像中可执行文件所在的目录。卷不会与映像合并,它们会像任何其他 Linux 文件系统挂载一样挂载在文件系统树中。这意味着挂载点的父文件系统中的文件不再可见。 (请注意,命名卷是由 docker 从映像内容中初始化的,但这仅在命名卷为空时发生。)因此,解决方法是不要将卷安装在您想要从映像运行的可执行文件的路径之上。
如果您为不同的平台运行二进制文件,并且没有使用 --fix-binary 选项配置 binfmt_misc,qemu 将在容器文件系统命名空间而不是主机文件系统中寻找解释器。有关此问题的更多详细信息,请参阅此 Ubuntu 错误报告。
如果错误来自 shell 脚本,则问题通常出在该脚本的第一行(例如 #!/bin/bash)。由于上述原因,该命令在图像中不存在,或者该文件未使用 Linux 换行符保存为 ascii 或 utf8。你可以尝试 dos2unix 来修复换行,或者检查你的 git 和编辑器设置。
问题是 glibc,它不是 apline base iamge 的一部分。
添加后它对我有用:)
以下是获取 glibc 的步骤
apk --no-cache add ca-certificates wget
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.28-r0/glibc-2.28-r0.apk
apk add glibc-2.28-r0.apk
我在构建高山基础映像时收到此错误消息:
ERROR: for web Cannot start service web: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "bash": executable file not found in $PATH: unknown
在我的 docker-compose
文件中,我有命令指令,其中使用 bash 执行命令,而 bash 不附带 alpine 基本映像。
command: bash -c "python manage.py runserver 0.0.0.0:8000"
然后我使用 sh
(shell) 实现并执行了命令。它对我有用。
参考标题。
我的错误是在 docker run
期间通过 --env-file
放置变量。其中,该文件包含一个 PATH
扩展名:PATH=$PATH:something
,这导致 PATH
var 看起来像 PATH=$PATH:something
(未执行 var 解析)而不是 PATH:/usr/bin...:something
。
我无法通过 --env-file
进行解析,因此我看到此问题的唯一方法是在 Dockerfile 中使用 ENV
。
我使用 docker-compose
遇到了这个问题。此处或 this related question 上的解决方案均未解决我的问题。最终对我有用的是使用 docker prune -a
清除所有缓存的 docker 工件并重新启动 docker。
要使其工作,请添加对 /usr/bin 的软引用:
ln -s $(哪个节点) /usr/bin/node
ln -s $(哪个 npm) /usr/bin/npm