简体   繁体   English

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

[英]How to configure Dockerfile correctly to run on Google Cloud Run?

I'm trying to run a Go app using Docker on Google Cloud Run but I'm getting this error: 我正在尝试使用Docker在Google Cloud Run上运行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.

I fixed my port to be 8080 as stated in the docs but I think my Dockerfile is incorrect. 我按照文档中所述将端口固定为8080 ,但我认为我的Dockerfile不正确。 Does anyone know what I'm missing? 有人知道我在想什么吗?

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 don't make your application listen on a specific port number. Dockerfile不会使您的应用程序侦听特定的端口号。

The EXPOSE directive in Dockerfile is purely a documentation and doesn't do anything functional. EXPOSE中的EXPOSE指令纯粹是一个文档,没有任何功能。

You have 2 options for a Go app: Go应用程式有2个选项:

  1. Just refactor your code to read the PORT env variable: os.Getenv("PORT") and use it on the HTTP server address you're starting: 只需重构代码即可读取PORT env变量: os.Getenv("PORT")并在您要启动的HTTP服务器地址上使用它:

     port := os.Getenv("PORT") http.ListenAndServe(":"+port) 
  2. Create a -port flag and read it during the entrypoint of your app in the Dockerfile: 创建-port标志并在Dockerfile中应用程序的入口点期间读取它:

    eg if you can make go run main.go -port=8080 work, change your dockerfile to: 例如,如果您可以go run main.go -port=8080 ,请将您的dockerfile更改为:

     exec go run main.go -port=$PORT 

These will get you what you want. 这些将为您提供所需的东西。

Ideally you should not use go run inside a container. 理想情况下,您不应在容器内使用go run Just do: 做就是了:

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

to compile a Go program and use it directly. 编译Go程序并直接使用它。 Otherwise, every time Cloud Run starts your container, you would be re-compiling it from scratch, which is not fast, this will increase your cold start times. 否则,每次Cloud Run启动容器时,您都会从头开始重新编译它,这不是很快,这会增加冷启动时间。


Aside from these you seem to have a lot of inconsistencies in your dockerfile. 除此之外,您的dockerfile中似乎还有很多不一致之处。 You set a lot of Go env vars like GOOS GOARCH but you don't actually go build your app ( go run is an on-the-fly compilation and doesn't take the linker flags in GOFLAGS into account I believe). 您设置了很多Go Env变量,例如GOOS GOARCH,但实际上并没有go build您的应用程序(我相信go run是即时编译,并且没有考虑GOFLAGS中的链接器标志)。 Look at sample Go dockerfiles to have a better idea on how to write idiomatic Go dockerfiles. 查看示例Go dockerfile,以更好地了解如何编写惯用的Go dockerfile。

It seems that you are missing the EXPOSE in your Dockerfile. 似乎您在EXPOSE中缺少EXPOSE。 See https://docs.docker.com/engine/reference/builder/#expose 参见https://docs.docker.com/engine/reference/builder/#expose

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM