PreviewDrop for Go

Deploy previews for Go apps

Push a branch, get a live preview URL. PreviewDrop compiles your Go binary in a multi-stage build, runs it as a long-lived process, and posts the link to the pull request in under 60 seconds.

TL;DR
Add a multi-stage Dockerfile, connect your repo, push. PreviewDrop builds a static binary and runs it behind a TLS-terminated subdomain. Your background goroutines, websocket connections and in-memory caches all work because it’s one real process — not a per-request serverless function with a 10-second ceiling.

Dockerfile

Drop this at the root of your repo. PreviewDrop picks it up on the next push and builds it into a container behind a TLS-terminated subdomain.

Dockerfile
FROM golang:1.23-alpine AS build WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . # Static binary so a distroless/scratch runtime works RUN CGO_ENABLED=0 go build -o /app . FROM gcr.io/distroless/static-debian12 COPY --from=build /app /app EXPOSE 8080 ENV PORT=8080 CMD ["/app"]

Environment variables

Set these in the Variables tab of your PreviewDrop project. They're encrypted at rest and injected into every preview container at start.

VariableExample valueNote
PORT8080PreviewDrop injects this. Read it in main() and listen on it.
DATABASE_URLpostgres://user:pass@host:5432/dbPoint at a shared dev DB, or omit for stateless / in-memory previews.
GIN_MODEreleaseIf you use Gin — silences debug logging. Equivalent flags exist for Echo / Fiber.

Common gotchas

Listen on 0.0.0.0 and read PORT from the environment

Bind with http.ListenAndServe(":"+os.Getenv("PORT"), mux). A colon-prefixed address binds all interfaces; binding to 127.0.0.1 makes the container unreachable from the proxy and the preview will 502.

CGO_ENABLED=0 for a static binary

The runtime stage uses a distroless static image with no libc. Build with CGO_ENABLED=0 so the binary is fully static. If you genuinely need cgo (e.g. a SQLite driver), swap the runtime to debian:bookworm-slim instead.

Point the build at the right main package

go build -o /app . assumes package main is at the repo root. If your entrypoint lives under cmd/server, build ./cmd/server instead.

Distroless has no shell

The static-debian runtime ships no sh, so use the exec-form CMD (["/app"]) and read all config from environment variables rather than a shell wrapper script.

Why not Vercel or Netlify?

Vercel supports Go only as serverless functions — one exported handler per file, a hard request timeout, and no process that outlives a request. A real Go HTTP server with background goroutines, websockets, ticker loops and shared in-memory state simply doesn’t fit that model. PreviewDrop runs your compiled binary as a persistent process — identical to how it runs in production.

Preview your Go app in 5 minutes

Connect a repo, push a branch, get a URL. No credit card, no trial clock.

Start free