![](/img/trans.png)
[英]standard_init_linux.go:190: exec user process caused "no such file or directory" Docker with go basic web app
[英]standard_init_linux.go:190: exec user process caused "no such file or directory" - Docker
當我在 Windows 10 上運行我的 docker 映像時。我收到此錯誤:
standard_init_linux.go:190: exec user process caused "no such file or directory"
我的碼頭文件是:
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
嘗試的方法1:嘗試將 #!/bin/sh 更改為 #!/bin/bash但得到相同的錯誤。
嘗試的方法2:在docker文件中添加了dos2unix
RUN apt-get install -y dos2unix
RUN dos2unix /run.sh
使用記事本++,進入編輯-> EOL 轉換-> 從CRLF 更改為LF。
更新:對於 VScode 用戶:您可以通過單擊狀態欄右下方的 CRLF 將 CRLF 更改為 LF
使用alpine
圖像時我遇到了同樣的問題。
我的.sh
文件有以下第一行:
#!/bin/bash
Alpine 沒有 bash。 所以將行更改為
#!/bin/sh
或安裝 bash
apk add --no-cache bash
為我解決了這個問題。
假設您在 alpine 容器中運行 go 二進制文件時遇到了這個問題。 在構建 bin 之前導出以下變量
# CGO has to be disabled for alpine
export CGO_ENABLED=0
然后go build
在我的情況下,我不得不將run.sh
文件的行結尾從CRLF
更改為LF
並且錯誤消失了。
“沒有這樣的文件或目錄”來自 Linux,我看到了以下原因:
第一個原因實際上並沒有在您的容器中包含文件。 有些人試圖從主機運行命令而不將其添加到他們的圖像中。 有些人通過在他們想要運行的命令之上安裝一個卷來隱藏他們的命令。 如果您運行相同的容器,但使用 shell 而不是正常的 entrypoint/cmd 值,並運行ls /path/to/cmd
您會看到它是否存在。
下一個原因是運行錯誤的命令。 這通常出現在運行命令的 json/exec 格式無法正確解析的情況下。 如果您看到一個命令試圖運行["app",
或類似的東西,則 Docker 沒有解析 json 字符串,Linux 正在嘗試使用 shell 將命令解析為字符串。 如果您對 args 進行了錯誤排序,例如嘗試運行,也可能會發生這種情況-it
這是您嘗試在圖像名稱之后放置標志的標志,而它們必須放在圖像名稱之前。
使用 shell 腳本,如果第一行帶有#!
則會出現此錯誤。 指向容器內不存在的命令。 對於某些人來說,這是試圖在只有/bin/sh
的圖像中運行bash
。 在您的情況下,這可以來自腳本中的 Windows 換行符。 在你的編輯器中切換到 Linux/Unix 換行將糾正這個問題。
對於二進制文件,如果缺少鏈接庫,則會出現此錯誤。 我經常在使用libc
編譯的 Go 命令時看到這種情況,但在 alpine 上使用musl
或從頭開始運行時根本沒有任何庫。 您需要包含所有缺少的庫或靜態編譯您的命令。 要查看這些庫鏈接,請在二進制文件上使用ldd /your/app
。
這是一個 CRLF 問題。 我用這個解決了這個問題:
git config --global core.eol lf
git config --global core.autocrlf input
find . -type f -print0 | xargs -0 dos2unix
請注意類似的錯誤,例如:
standard_init_linux.go:211: exec user process caused "no such file or directory"
如果構建映像的架構與您的系統不匹配,則可能會發生這種情況。 例如,嘗試在x86_64
機器上運行為arm64
構建的映像可能會產生此錯誤。
我在使用 CGO 構建應用程序時遇到了這個問題,然后將其復制到scratch
圖像。 那里不存在 Libc,所以我使用alpine
作為我的基本映像。
使用 Notepad++ 將 CRLF 替換為 LF
重建並運行 docker 映像應該可以解決您的問題。
這是因為shell腳本在windows中是格式化的,我們需要改成unix格式。 您可以在任何 Linux 系統上運行 dos2unix 命令。
dos2unix your-file.sh
如果您無法訪問 Linux 系統,您可以使用帶有 dos2unix.exe 的 Git Bash for Windows
dos2unix.exe your-file.sh
在x86
機器上構建基於ARM
的 docker 映像時,我收到了相同的錯誤消息。 通過安裝QEMU並注冊腳本解決了這個問題
#Install the qemu
sudo apt-get install qemu binfmt-support qemu-user-static packages
#This step will execute the registering scripts
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
我正在構建一個Go應用程序,這些答案中的每一個對我來說都是錯誤的,所以我想分享我的解決方案。 對我來說,我有一個不涉及 Windows 的 Dockerfile(在 Mac 上編碼,盡管在 macOS 11 上的一個和 macOS 12 上的另一個之間共享。但行結尾是相同的)。
對我來說,解決方案最終是我需要將我的應用程序構建為一個靜態鏈接的二進制文件,該二進制文件將在沒有外部依賴項的情況下運行。 我正在為一個 Go 應用程序構建一個 Dockerfile,該應用程序首先在 Go 構建器映像中構建,然后在臨時映像中構建。 為了讓我的二進制文件能夠從頭開始運行,我必須添加CGO_ENABLED=0
標志。 有關此 reddit 頁面的更多信息: https ://www.reddit.com/r/golang/comments/pi97sp/comment/hbo0fq6/?utm_source=share&utm_medium=web2x&context=3
我的代碼,最終工作:
############################
# STEP 1 build optimized executable binary
############################
FROM golang:1.16-alpine AS builder
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o cl-api
############################
# STEP 2 build a small image
############################
FROM scratch
COPY --from=builder /app/cl-api /
EXPOSE 8000
ENTRYPOINT ["/cl-api"]
問題:
問題來自.sh文件。 首先我們必須記住, Windows使用\r\n作為行尾,而Linux 和 Mac使用\n 。 Git 有一個名為 autoclrf 的功能,在 Windows 上通常設置為“true”。 這會在從 Git 存儲庫完成下載后自動將\n轉換為\r\n ,但 Git 不會對此進行任何形式的通知,因此會生成錯誤。 這個過程是好的,至少對於其他文件來說是這樣,但對於 bash 文件卻不是這樣,對於entrypoint.sh文件也是如此。
即時解決方案:
打開您最喜歡的代碼編輯器並更改導致沖突的文件的行尾,在我們的例子中: entrypoint.sh 。 您可以在軟件右下角的 Visual Studio Code 中執行此操作,單擊顯示CRLF的位置並將文件行尾更改為LF 。
從以下鏈接閱讀整篇文章以獲得永久解決方案:
將此添加到您的 Dockerfile
RUN cat /run.sh | tr -d '\r' > /run.sh
我解決了一個類似的問題
我的配置: -> Docker Desktop WSL 2 后端 - Windows -> 需要 CGO_ENABLED=1,因為我使用 Lib confluent-kafka-go.v1/kafka 編譯了一個 Kafka Producer
我的 docker 鏡像已經構建成功,但是當我使用 docker-compose-up 啟動鏡像時,會出現同樣的問題:
xxxxx:~/cp-all-in-one/cp-all-in-one-community# docker-compose up
Recreating ms-c3alert ... done
Attaching to ms-c3alert
ms-c3alert | standard_init_linux.go:211: exec user process caused "no such file or directory"
ms-c3alert exited with code 1
之后,測試線程和其他頁面中的所有選項...我發現在 go build 語句中添加了修復 -ldflags='-w -extldflags "-static" '
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags='-w -extldflags "-static"' -a -installsuffix cgo -o c3alert .
我的.sh
文件末尾多了一行。 我刪除了它並解決了這個問題。
如果嘗試在從頭開始的容器中運行動態鏈接的可執行文件,也會出現此錯誤。 可執行文件將無法鏈接到共享 ( so
) 庫,並且會報告(信息量不大)“沒有這樣的文件或目錄”錯誤。
讓我們構建一個動態的可執行test
:
cat <<EOF | g++ -x c++ - -o test
#include <iostream>
int main() {
std::cerr << "Hello!" << std::endl;
return 0;
}
EOF
這確實是一個動態可執行文件。 運行ldd test
將報告類似(依賴於 libc 等):
linux-vdso.so.1 (0x00007ffd699fc000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff570f7a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff570c76000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff570a5f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff5706c0000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff5714fe000)
現在,讓我們使用以前的可執行文件構建一個從頭開始的映像。 Dockerfile 將是:
FROM scratch
COPY test /
CMD [ "/test" ]
構建圖像。 然后,從圖像運行一個即時容器:
docker build . -t local/test
docker run --rm local/test
容器失敗,退出代碼為 1,我得到:
standard_init_linux.go:219: exec user process caused: no such file or directory
通過使用靜態鏈接(在先前的gcc
/ g++
鏈接器命令中使用-static
標志)解決了該問題,該鏈接產生了一個獨立的可執行文件。
我解決了這個問題,在 vscode 中設置了我的設置。
問候
我發現了一個特殊的邊緣案例,我在alpine容器中使用了tini init ,但是由於我沒有使用靜態鏈接版本,並且Alpine 使用 musl libc 而不是默認安裝的 GNU LibC 庫,因此它與相同的崩潰錯誤信息。
如果我理解這一點並花時間正確閱讀文檔,我會發現Tini Static ,它在更改為后解決了我的問題。
這里有多個正確答案。 我沒有看到它的 VIM 版本,所以在這里。 在 VIM 中打開文件,例如檢查底部狀態行,執行set ff=dos
(對於 CRLF)或set ff=unix
(對於 LF)。
您可以在 Mac 上使用 BBEdit 來解決此問題,因為 Notepad++ 不可用。
在窗口底部很明顯。 除了字符集選項
git config core.autocrlf false
git rm --cached -r .
git reset --hard
我在使用以下構建時遇到了類似的問題
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"]
干杯。
當在運行時找不到動態庫時,它會返回這個
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.