Run Fiber on Kubernetes

Khimananda Oli 7 min read Programming and Languages
Run Fiber on Kubernetes

By Khimananda Oli | Last reviewed: August 2026

You want to run Fiber on Kubernetes because your Go API needs raw throughput and low latency that traditional frameworks cannot match at scale. While Fiber’s performance is exceptional, deploying it requires specific containerization and orchestration patterns to avoid common pitfalls like improper signal handling or resource starvation. This guide covers the exact configuration I use in production to bridge the gap between local development and a resilient, autoscaling cluster.

How do you containerize Go Fiber for Kubernetes?

The foundation of any reliable deployment is the container image. When you run Fiber on Kubernetes, you must avoid shipping source code or heavy base images. A proper multi-stage build reduces your attack surface and ensures consistent startup times across environments. In my experience auditing SOC 2 compliance for fintech clients, minimizing the final image size is often the first control verified during security reviews.

Builder Stagegolang:1.23-alpineCGO_ENABLED=0go build -ldflags="-s"Static BinaryRuntime Stagealpine:3.19 / scratchCOPY --from=builderUSER nonroot:nonrootFinal Image< 15 MBSecure & Fast
Figure 1: Multi-stage build architecture optimized to run Fiber on Kubernetes securely

Your Dockerfile should explicitly disable CGO unless you have a specific dependency requiring it. Static binaries eliminate libc version mismatches between build and runtime environments. Here is a production-tested Dockerfile pattern:

# Build stage
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
    -ldflags="-w -s -extldflags '-static'" \
    -o server .

# Runtime stage
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata curl
WORKDIR /root/
COPY --from=builder /app/server .
RUN adduser -D -H -u 1000 appuser
USER appuser
EXPOSE 3000
CMD ["./server"]

Note the inclusion of curl in the runtime stage. While some purists prefer scratch, Alpine with curl enables native HTTP-based liveness probes without installing additional binaries. For teams managing Kubernetes secrets management, this base also provides necessary tools for debugging authentication issues during incident response.

What are the correct health check configurations for Fiber?

Fiber uses fasthttp under the hood, which behaves differently than net/http. A common mistake when engineers first run Fiber on Kubernetes is configuring TCP probes instead of HTTP probes. TCP probes only verify that the socket is open, not that the application can actually process requests. You must implement dedicated health endpoints that validate downstream dependencies.

Implementing Native Health Endpoints

Add explicit routes for liveness and readiness. Liveness should be lightweight—just confirming the event loop isn't blocked. Readiness should check database connections, cache availability, and external service dependencies.

app.Get("/healthz/live", func(c *fiber.Ctx) error {
    return c.JSON(fiber.Map{"status": "ok"})
})

app.Get("/healthz/ready", func(c *fiber.Ctx) error {
    if err := db.Ping(); err != nil {
        return c.Status(503).JSON(fiber.Map{
            "status": "unavailable", 
            "reason": err.Error()
        })
    }
    return c.JSON(fiber.Map{"status": "ready"})
})

Kubernetes Probe Configuration

Configure your Deployment manifest to use these endpoints. Set appropriate timeouts and thresholds based on your application's actual startup behavior. I typically see Fiber apps start in under 2 seconds, but always measure before setting values.

  • livenessProbe: HTTP GET /healthz/live, initialDelaySeconds: 5, periodSeconds: 10, failureThreshold: 3
  • readinessProbe: HTTP GET /healthz/ready, initialDelaySeconds: 2, periodSeconds: 5, failureThreshold: 2
  • startupProbe: HTTP GET /healthz/live, initialDelaySeconds: 0, periodSeconds: 1, failureThreshold: 30 (protects slow starts)

For deeper observability integration, consider pairing these probes with the patterns described in instrumenting an app with OpenTelemetry to correlate probe failures with trace data.

How do you configure resource limits and autoscaling?

Fiber’s efficiency means you can handle more requests per CPU core than most frameworks, but this creates a counterintuitive scaling challenge. If you set requests too low, the scheduler may pack too many pods onto a node, causing noisy-neighbor issues during traffic spikes. If you set them too high, you waste resources and delay scaling decisions.

Node ResourcesFiber Pod AReq: 250m CPU / 256MiFiber Pod BReq: 250m CPU / 256MiOther WorkloadReq: 500m CPU / 512MiUnallocated BufferMetrics ServerCPU / Memory / CustomAvg CPU: 78%Target: 70%HPAScale UpMin: 2Max: 10Cooldown: 60s
Figure 2: Resource allocation strategy and HPA decision flow when you run Fiber on Kubernetes

Setting Requests vs Limits

For CPU-bound Go applications like Fiber, set requests equal to limits. This guarantees predictable scheduling and prevents throttling during peak loads. Memory should have a small buffer between request and limit to accommodate GC spikes.

ConfigurationDevelopmentProduction (Recommended)Rationale
CPU Request100m250m–500mMatches typical single-goroutine baseline
CPU Limit500m= RequestPrevents CFS throttling on shared cores
Memory Request128Mi256Mi–512MiBased on p99 heap usage + GC headroom
Memory Limit256MiRequest × 1.2Avoids OOMKill during transient allocations
GOMAXPROCSAutoMatch CPU LimitPrevents excessive context switching

Always set GOMAXPROCS explicitly to match your CPU limit. The Go runtime defaults to host CPU count, which causes severe performance degradation in containers. Use uber-go/automaxprocs or set it manually in your entrypoint.

Horizontal Pod Autoscaler Tuning

Start with CPU-based scaling at 70% target utilization. Fiber handles concurrency efficiently, so CPU correlates well with actual load. Avoid memory-based HPA for Go apps unless you have known leak patterns. Configure stabilization windows to prevent flapping:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: fiber-api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: fiber-api
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
      - type: Pods
        value: 2
        periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
      - type: Pods
        value: 1
        periodSeconds: 120

How do you handle graceful shutdowns and zero-downtime deploys?

Fiber supports graceful shutdown natively, but Kubernetes doesn’t wait indefinitely. Your pod’s terminationGracePeriodSeconds must exceed your longest expected request duration plus shutdown cleanup time. I recommend 30 seconds as a starting point for most APIs, extending to 60+ for endpoints processing large uploads or complex transactions.

Signal Handling Implementation

Ensure your main function properly catches SIGTERM and initiates shutdown. Fiber’s Shutdown() method stops accepting new connections while completing in-flight requests.

go func() {
    sigChan := make(chan os.Signal, 1)
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
    <-sigChan
    
    log.Info("Received shutdown signal, draining connections...")
    if err := app.ShutdownWithTimeout(25 * time.Second); err != nil {
        log.Errorf("Shutdown error: %v", err)
    }
}()

if err := app.Listen(":3000"); err != nil {
    log.Fatalf("Server failed: %v", err)
}

Pair this with a preStop hook that sleeps for 5 seconds. This allows the kube-proxy and ingress controller to update endpoints before your app stops serving, preventing connection resets during rolling updates. For teams implementing blue-green and canary deploys on Kubernetes, this hook is non-negotiable.

What networking and ingress patterns work best for Fiber?

Fiber’s performance can be bottlenecked by misconfigured ingress controllers. Since Fiber speaks HTTP/1.1 and HTTP/2 natively, ensure your ingress terminates TLS correctly and forwards real client IPs. Most ingress controllers require specific annotations to preserve headers that Fiber expects for rate limiting and logging.

ClientHTTPS :443TLS 1.3Ingress ControllerTLS TerminationX-Forwarded-ForX-Real-IPHTTP/2 → HTTP/1.1Cluster IPFiber Pods (ReplicaSet)Pod 1:3000Pod 2:3000Pod N:3000
Figure 3: Network topology and header propagation when you run Fiber on Kubernetes behind an ingress

Enable proxy protocol support if your load balancer requires it. Configure Fiber’s EnableTrustedProxyCheck and TrustedProxies settings to match your cluster’s CIDR ranges. Without this, rate limiters and audit logs will record internal IPs instead of real client addresses—a frequent issue I encounter during structured logging audits.

Run Fiber on Kubernetes With Confidence

Successfully deploying high-performance Go services requires attention to containerization details, probe semantics, and resource tuning that generic tutorials often skip. When you run Fiber on Kubernetes using the patterns above—multi-stage builds, proper health checks, matched CPU requests/limits, and graceful shutdown handling—you get a platform that scales predictably under real production load. Start with the Dockerfile and probe configuration, validate locally with kind or minikube, then apply the HPA and networking settings incrementally. If your team needs help designing a compliant, observable deployment pipeline for Go microservices, reach out to discuss your infrastructure requirements.

Frequently Asked Questions

Use a multi-stage Dockerfile with golang:1.23-alpine for building and alpine:3.20 for runtime. Copy only the compiled binary to reduce image size below 20MB. Set the entrypoint to the binary directly, avoiding shell wrappers to ensure proper signal handling within pods.

Configure Fiber to listen on port 8080 or 3000 internally. Avoid privileged ports like 80 to prevent requiring root permissions. Map this container port in your deployment manifest and reference it consistently in Service definitions for reliable cluster networking.

Yes. Fiber v3 handles SIGTERM signals natively when using app.Listen(). Ensure your deployment spec sets terminationGracePeriodSeconds adequately, typically thirty seconds, allowing active requests to complete before the container is forcibly killed during rolling updates or scaling events.

Expose a dedicated health endpoint returning HTTP 200. Configure httpGet liveness probes in your deployment YAML pointing to this path. Set initialDelaySeconds to five and periodSeconds to ten to prevent premature restarts while the Go runtime initializes and warms up.

Fiber uses fasthttp with zero memory allocation per request, offering lower latency and higher throughput than Gin under load. This efficiency translates to fewer required replicas and reduced compute costs when running high-traffic services on Kubernetes clusters in 2026.

Use ConfigMaps for non-sensitive configuration and Secrets for credentials. Reference them in your deployment env section or mount as files. Fiber reads os.Getenv natively, so standard Kubernetes environment variable injection works without additional libraries or custom configuration loaders.

Start with 100m CPU and 128Mi memory requests. Fiber is lightweight but monitor actual usage with Prometheus. Adjust limits based on p99 latency metrics rather than averages, as Go garbage collection spikes can cause throttling if CPU limits are too restrictive.

Let ingress controllers like NGINX or Traefik handle TLS termination. Run Fiber over plain HTTP internally to avoid certificate management complexity. Use cert-manager for automated certificate provisioning and renewal at the ingress layer, keeping application containers simple and stateless.

Yes. Use standard DNS names like service-name.namespace.svc.cluster.local for inter-service communication. Fiber's fasthttp client resolves these names through the pod's DNS resolver. No special service mesh integration is required unless you need advanced traffic management features.

Enable pprof endpoints and expose them via a separate port. Use kubectl port-forward to access profiling data locally. Check for GC pressure, connection pool exhaustion, or slow downstream dependencies. Correlate traces with OpenTelemetry instrumentation added to Fiber middleware.

Output structured JSON logs to stdout using zerolog or zap. Include request ID, trace ID, and status code fields. This format integrates directly with Fluent Bit or Vector collectors, enabling efficient parsing and indexing in observability platforms without log file management overhead.

Configure Horizontal Pod Autoscaler targeting CPU utilization or custom metrics from Prometheus Adapter. Fiber's low per-request overhead means CPU scales linearly with traffic. Set minReplicas to two for availability and maxReplicas based on backend capacity constraints and budget limits.

Generally no. Fiber handles concurrent connections efficiently without nginx buffering. Only add Envoy or nginx sidecars if you require specific features like request retries, circuit breaking, or mTLS that your ingress controller cannot provide at the edge.

Store config in ConfigMaps and use Reloader or similar controllers to trigger rolling restarts on change. Alternatively, implement dynamic config loading via file watchers. Never embed environment-specific values in container images to maintain immutable deployment artifacts across staging and production.

Running as root, missing health checks, ignoring graceful shutdown, and setting overly aggressive resource limits. Always use non-root users, define proper probes, respect SIGTERM, and base resource allocations on observed metrics rather than guesses to ensure stable production operations.