当我在windows 10上运行docker映像时。我得到这个错误:

standard_init_linux.go:190: exec user process caused "no such file or directory"

我的docker文件是:

FROM openjdk:8

EXPOSE 8080

VOLUME /tmp

ADD appagent.tar.gz /opt/app-agent
ADD services.jar app.jar
ADD run.sh /run.sh

# Install compiler and perl stuff
RUN apt-get update
RUN apt-get install -y build-essential
RUN apt-get install -y gcc-multilib
RUN apt-get install -y perl

# Install Percona Toolkit
RUN apt-get install --yes percona-toolkit
RUN ["chmod", "+x", "/run.sh"]
ENTRYPOINT ["/run.sh"]

脚本以#!开头/bin/sh

#!/bin/sh
set -e

JAVA_OPTS="-Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/urandom"

if [ "${APPD_APP_NAME}" != "" ]; then
JAVA_AGENT="-javaagent:/opt/app-agent/javaagent.jar
fi

exec java ${JVM_OPTS} ${JAVA_OPTS} ${JAVA_AGENT} -jar /app.jar

尝试method1: 试着改变#!/bin/sh到#!/bin/bash但是得到同样的错误。

尝试method2: docker文件中新增dos2unix

RUN apt-get install -y dos2unix
RUN dos2unix /run.sh

当前回答

我发现了一个特殊的边缘情况,我在一个alpine容器中使用tini init,但由于我没有使用静态链接的版本,并且alpine使用musl libc而不是默认安装的GNU libc库,它崩溃了,并出现了完全相同的错误消息。

如果我明白这一点,并花时间阅读文档,我就会找到Tini Static,它在更改后解决了我的问题。

其他回答

这是CRLF的问题。我用这个解决了这个问题:

git config --global core.eol lf

git config --global core.autocrlf input

find . -type f -print0 | xargs -0 dos2unix

我只是想补充:对于VSCode用户,您可以通过单击状态栏中的CRLF将CRLF行结束符更改为LF,然后选择LF并保存文件。

我也有同样的问题,这个解决了问题。

“没有这样的文件或目录”来自Linux,我看到了以下原因:

第一个原因是容器中没有文件。有些人试图从主机运行命令,而不将其添加到映像中。有些人通过在他们想要运行的命令之上安装一个卷来掩盖他们的命令。如果你运行相同的容器,但是使用shell而不是普通的entrypoint/cmd值,并运行ls /path/to/cmd,你会看到它是否存在。

下一个原因是运行了错误的命令。这通常出现在json/exec格式的命令不能正确解析的情况下。如果你看到一个命令试图运行["app",或类似的东西,json字符串没有被Docker解析,Linux正试图使用shell将该命令解析为字符串。如果你打乱了参数的顺序,这也会发生,例如,试图运行-这是一个标志,你试图把标志放在图像名称之后,而它们必须放在图像名称之前。

对于shell脚本,如果第一行带有#!指向容器中不存在的命令。对于某些人来说,这是试图在只有/bin/sh的映像中运行bash。在你的例子中,这可以来自脚本中的Windows换行。在编辑器中切换到Linux/Unix换行将会纠正这个错误。

对于二进制文件,如果缺少链接库,则出现此错误。我经常看到这样的情况:使用libc编译的Go命令,但在alpine上使用musl或scratch运行,根本没有任何库。您需要包含所有缺失的库,或者静态编译您的命令。要查看这些库链接,请在二进制文件中使用ldd /your/app。

在使用下面的代码构建时,我遇到了类似的问题

FROM golang:1.18.0-alpine3.15 AS builder

WORKDIR /go/src/blah
COPY . .

RUN go get -d -v ./...
RUN go install -v ./...

WORKDIR /go/src/blah

FROM centos AS runtime   ## NOTICE THE DISTRO CHANGE HERE
COPY --from=builder /go/bin/blah /bin/blah

CMD ["blah"]

以下是我的解决方案(与上面概述的相同,但添加了供人们检查)

FROM golang:1.18.0-alpine3.15 AS builder

WORKDIR /go/src/blah
COPY . .

RUN go get -d -v ./...
RUN export CGO_ENABLED=0 && go install -v ./...    <== added during install/build

WORKDIR /go/src/blah

FROM centos AS runtime
COPY --from=builder /go/bin/blah /bin/blah

CMD ["blah"]

欢呼。

使用notepad++,进入编辑-> EOL转换->从CRLF更改为LF。

更新:对于VScode用户:您可以通过单击状态栏右下角的CRLF来更改CRLF