Reputation: 1838
I'm trying to run a Go app using Docker on Google Cloud Run but I'm getting this error:
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. 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" ]
Upvotes: 3
Views: 3462
Reputation: 45302
Dockerfiles don't make your application listen on a specific port number.
The EXPOSE
directive in Dockerfile is purely a documentation and doesn't do anything functional.
You have 2 options for a Go app:
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 := os.Getenv("PORT")
http.ListenAndServe(":"+port)
Create a -port
flag and read it during the entrypoint of your app in the Dockerfile:
e.g. if you can make go run main.go -port=8080
work, change your dockerfile to:
exec go run main.go -port=$PORT
These will get you what you want.
Ideally you should not use go run
inside a container. Just do:
RUN go build -o /bin/my-app ./my/pkg
ENTRYPOINT /bin/my-app
to compile a Go program and use it directly. 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.
Aside from these you seem to have a lot of inconsistencies in your 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). Look at sample Go dockerfiles to have a better idea on how to write idiomatic Go dockerfiles.
Upvotes: 8
Reputation: 402
It seems that you are missing the EXPOSE
in your Dockerfile. See https://docs.docker.com/engine/reference/builder/#expose
Upvotes: -1