Go

Last updated

Go is not one of the runtimes the zip agent builds from source. It detects Python, Node.js and prebuilt .NET; a Go project uploaded as a zip won't be recognised.

That's less of a limitation than it sounds, because Go is one of the best-fitting workloads here and a Dockerfile for it is short.

Use a Dockerfile and git push

A multi-stage build gives you a container measured in single-digit megabytes:

FROM golang:1-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./...

FROM gcr.io/distroless/static
COPY --from=build /app /app
ENTRYPOINT ["/app"]

Put that at the repository root and push to deploy. Dependencies are downloaded before the source is copied, so a code change doesn't re-download the module cache.

Why Go suits this platform

  • A static binary — no interpreter, no runtime to install, no dependency resolution at startup.
  • Tiny images, which means short pulls and therefore short deploys.
  • Low idle memory, so the smallest presets go a long way.

A Go bot or worker is about as small as a hosted process gets.

Two things to get right

Bind 0.0.0.0. A bare :8080 binds all interfaces, which is what you want; 127.0.0.1:8080 is unreachable from outside the container and nothing will catch it for you.

Set GOMAXPROCS if you're on Go 1.24 or earlier. Older runtimes size their scheduler from the host's core count rather than your container's CPU allocation, which on a fractional CPU means far more parallelism than you have budget for. Go 1.25 and later read the container limit automatically.

A scratch image is still debuggable

Shipping a binary in scratch or distroless doesn't cost you access — a static busybox is mounted into every container, so the Shell and Files tabs work even when your image contains nothing but the binary.

If you only have a compiled binary

If you can't build here and only have a prebuilt Linux amd64 executable, wrap it in a minimal Dockerfile rather than uploading it as a zip:

FROM debian:bookworm-slim
COPY myapp /usr/local/bin/myapp
ENTRYPOINT ["myapp"]

Use debian:bookworm-slim rather than scratch unless the binary is fully static — dynamically linked binaries need their libraries present.