← Kembali

Go Pemula Utility

HTTP healthcheck server minimal di Go

Server Go 30 baris yang expose /health dan /ready endpoint. Cocok untuk Kubernetes liveness probe atau Cloudflare Tunnel.

Dipublikasikan 21 Mei 2026

Kadang yang dibutuhkan hanya HTTP server kecil yang merespon 200 OK untuk monitoring. Service di belakang Cloudflare Tunnel, sidecar untuk Kubernetes, atau status-check internal. Go cocok karena binary-nya kecil (~6 MB) dan startup cepat.

Kode

// healthcheck/main.go
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"
	"runtime"
	"time"
)

var startTime = time.Now()

type Status struct {
	Status     string        `json:"status"`
	Uptime     string        `json:"uptime"`
	StartedAt  string        `json:"started_at"`
	Memory     uint64        `json:"memory_mb"`
	Goroutines int           `json:"goroutines"`
	Version    string        `json:"version"`
}

func health(w http.ResponseWriter, r *http.Request) {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	
	status := Status{
		Status:     "ok",
		Uptime:     time.Since(startTime).Round(time.Second).String(),
		StartedAt:  startTime.UTC().Format(time.RFC3339),
		Memory:     m.Alloc / 1024 / 1024,
		Goroutines: runtime.NumGoroutine(),
		Version:    os.Getenv("APP_VERSION"),
	}
	
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(status)
}

func ready(w http.ResponseWriter, r *http.Request) {
	// Tambahkan check ke dependencies (DB, cache, dst) di sini
	// Contoh: cek koneksi DB; kalau gagal, return 503
	w.WriteHeader(http.StatusOK)
	fmt.Fprintln(w, "ready")
}

func main() {
	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	mux := http.NewServeMux()
	mux.HandleFunc("/health", health)
	mux.HandleFunc("/ready", ready)
	
	srv := &http.Server{
		Addr:         ":" + port,
		Handler:      mux,
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}

	log.Printf("Healthcheck server listening on :%s", port)
	if err := srv.ListenAndServe(); err != nil {
		log.Fatal(err)
	}
}

Build & run

go mod init healthcheck
go build -o healthcheck main.go

# Run
PORT=8080 APP_VERSION=v1.0.0 ./healthcheck

# Test
curl http://localhost:8080/health
# {"status":"ok","uptime":"1m23s","memory_mb":1,"goroutines":7,"version":"v1.0.0"}

Build untuk Docker

# Dockerfile
FROM golang:1.22-alpine AS build
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o healthcheck

FROM scratch
COPY --from=build /app/healthcheck /healthcheck
EXPOSE 8080
ENTRYPOINT ["/healthcheck"]

Hasilnya: image Docker ~6 MB total.

Kapan dipakai

  • Microservice yang butuh liveness/readiness probe Kubernetes.
  • Status page sidecar — di-poll oleh Uptime Robot, Healthchecks.io, atau Bettercheck.
  • Smoke test sebelum routing traffic ke deployment baru.

Catatan

  • Tidak ada dependency external — pakai net/http stdlib. Tidak butuh framework seperti Echo atau Fiber untuk use case sederhana ini.
  • runtime.MemStats ngecek heap saat ini, bukan keseluruhan memory process. Untuk metric yang akurat, pakai Prometheus client.
  • Cross-compile ke ARM (Raspberry Pi): GOOS=linux GOARCH=arm64 go build.
  • Graceful shutdown tidak ada di snippet ini. Untuk production, tambahkan signal handling:
go func() {
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatal(err)
    }
}()

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

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
srv.Shutdown(ctx)

Untuk Cloudflare Tunnel, cloudflared butuh service jalan di port yang ditentukan di config. Pakai snippet ini sebagai dummy service untuk test routing sebelum bikin app sungguhan.

# tags

healthcheckkubernetesuptimeminimal

← Semua snippet Snippet Go lain →