如何正确配置Dockerfile以在Google Cloud Run上运行?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (164)

我正在尝试使用Google Cloud Run上的Docker运行Go应用,但我收到此错误:

Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable. Logs for this revision might contain more information.

我修复了我的端口,8080如文档中所述,但我认为我的Dockerfile不正确。有谁知道我错过了什么?

FROM golang:1.12-alpine

RUN apk upgrade -U \
  && apk add \
  ca-certificates \
  git \
  libva-intel-driver \
  make \
  && rm -rf /var/cache/*

ENV GOOS linux
ENV GOARCH amd64
ENV CGO_ENABLED=0
ENV GOFLAGS "-ldflags=-w -ldflags=-s"
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
RUN echo $PATH
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
RUN go get -u github.com/cespare/reflex
# RUN reflex -h 
# Setup modules after reflex install
ENV GO111MODULE=on \
  GOFLAGS="$GOFLAGS -mod=vendor"

WORKDIR /go/src/bitbucket.org/team/app/

COPY . .

CMD [ "go", "run", "cmd/main.go" ]
提问于
用户回答回答于

Dockerfiles不会使您的应用程序侦听特定的端口号。

EXPOSEDockerfile中的指令纯粹是一个文档,并没有做任何功能。

Go应用程序有2个选项:

  1. 只需重构您的代码以读取PORTenv变量:os.Getenv("PORT")并在您正在启动的HTTP服务器地址上使用它: port := os.Getenv("PORT") http.ListenAndServe(":"+port)
  2. 创建一个-port标志并在Dockerfile中的应用程序入口点读取它: 例如,如果您可以go run main.go -port=8080工作,请将您的dockerfile更改为: exec go run main.go -port=$PORT

这些将为您提供您想要的。

理想情况下,你不应该使用go run的容器内。做就是了:

RUN go build -o /bin/my-app ./my/pkg
ENTRYPOINT /bin/my-app

编译Go程序并直接使用它。否则,每次Cloud Run启动容器时,您都会从头开始重新编译它,这不会很快,这会增加您的冷启动时间。

除了这些之外,你的dockerfile中似乎有很多不一致之处。你设置了许多Go env vars,比如GOOS GOARCH,但你实际上并不是go build你的应用程序(go run是一个即时编译,并且不考虑GOFLAGS中的链接器标志我相信)。查看示例Go dockerfiles以更好地了解如何编写惯用的Go dockerfiles。

扫码关注云+社区

领取腾讯云代金券