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.
DockerfileFROM 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.
| Variable | Example value | Note |
|---|---|---|
| PORT | 8080 | PreviewDrop injects this. Read it in main() and listen on it. |
| DATABASE_URL | postgres://user:pass@host:5432/db | Point at a shared dev DB, or omit for stateless / in-memory previews. |
| GIN_MODE | release | If 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