All posts

Go Application Deployment Checklist

A practical Go deployment checklist covering binary builds, health endpoints, graceful shutdown, configuration management, and observability.

Go Application Deployment Checklist

Go's compiled binaries simplify deployment, but there's still plenty to get right. Use this checklist.

Build Configuration

# Production build with version info
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
  -ldflags="-s -w -X main.version=$(git describe --tags)" \
  -o server ./cmd/server
  • [ ] CGO_ENABLED=0 for static binary (no libc dependency)
  • [ ] Version info embedded via -ldflags
  • [ ] Binary tested on target OS/arch
  • [ ] Reproducible builds with go.sum checked in

Graceful Shutdown

func main() {
    srv := &http.Server{Addr: ":8080", Handler: router}

    go func() {
        if err := srv.ListenAndServe(); err != http.ErrServerClosed {
            log.Fatalf("listen: %v", err)
        }
    }()

    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit

    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()
    if err := srv.Shutdown(ctx); err != nil {
        log.Fatalf("forced shutdown: %v", err)
    }
    log.Println("server stopped gracefully")
}
  • [ ] Graceful shutdown handles in-flight requests
  • [ ] Shutdown timeout configured (30s recommended)
  • [ ] Database connections closed on shutdown

Health Checks

http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    if err := db.PingContext(r.Context()); err != nil {
        w.WriteHeader(http.StatusServiceUnavailable)
        json.NewEncoder(w).Encode(map[string]string{"status": "unhealthy"})
        return
    }
    json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
})

Configuration

  • [ ] Config loaded from environment variables
  • [ ] Secrets never in source code or CLI args
  • [ ] Validation on startup — fail fast on missing config

Observability

  • [ ] Structured logging (zerolog or zap)
  • [ ] Error tracking with Bugsly for panic recovery
  • [ ] Metrics endpoint (/metrics for Prometheus)
  • [ ] Distributed tracing headers propagated

Container Deployment

FROM scratch
COPY server /server
EXPOSE 8080
ENTRYPOINT ["/server"]

Use scratch or distroless base images for minimal attack surface.

Try Bugsly Free

AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.

Get Started Free