我正在尝试在 docker 映像中安装 NPM 模块,并使用 Google App Engine 使用 golang 应用程序(flex)运行它。
main.go
:
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
cmd := exec.Command("rettiwt", "help")
output, err := cmd.CombinedOutput()
if err != nil {
// fmt.Println("Error:", err)
if err.Error() == "exec: \"rettiwt\": executable file not found in $PATH" {
// Print $PATH
fmt.Println("PATH:", os.Getenv("PATH"))
// Print the contents of /usr/local/bin
files, err := os.ReadDir("/usr/local/bin")
if err != nil {
panic(err)
}
fmt.Println("Contents of /usr/local/bin:", files)
}
panic(err)
}
fmt.Println("Output:", string(output))
}
Dockerfile
:
FROM golang:1.22
RUN apt-get update && apt-get install -y nodejs npm
RUN npm install -g rettiwt-api
ENV PATH="/usr/local/bin:$PATH"
WORKDIR /app
COPY . .
RUN go build -o app
CMD ["./app"]
app.yaml
:
runtime: go
env: flex
service: rettiwt
manual_scaling:
instances: 1
runtime_config:
operating_system: "ubuntu22"
runtime_version: "1.22"
我从
gcloud app deploy
命令收到以下错误:
...
Updating service [rettiwt] (this may take several minutes)...failed.
ERROR: (gcloud.app.deploy) Error Response: [9] An internal error occurred while processing task /app-engine-flex/flex_await_healthy/flex_await_healthy>2024-11-05T23:50:55.210Z5706.xa.0: PATH: /layers/google.go.build/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Contents of /usr/local/bin: []
panic: exec: "rettiwt": executable file not found in $PATH
goroutine 1 [running]:
main.main()
/workspace/main.go:24 +0x116
根据输出,看起来
$PATH
没问题,但是/usr/local/bin
是空的。
当我尝试在本地构建 docker 镜像时:
docker build -t my-rettiwt-app .
docker run -it my-rettiwt-app rettiwt help
它工作得很好,而且
rettiwt
确实在 /usr/local/bin
:
docker > ls -la /usr/local/bin
total 12
drwxr-xr-x 1 root root 4096 Oct 31 05:30 .
drwxr-xr-x 1 root root 4096 Sep 28 01:34 ..
lrwxrwxrwx 1 root root 43 Oct 31 05:30 rettiwt -> ../lib/node_modules/rettiwt-api/dist/cli.js
Google App Engine 的容器和本地容器之间是否存在一些行为差异?
我自己想出来了。
问题是,在
app.yaml
中,runtime: go
将使用预先构建的图像,而不是提供的Dockerfile
。
所以,解决方案就是:
runtime: custom
请注意: 要使用自定义运行时,您必须指定 Flex 环境 (
env: flex
)。