# podinfo: the Go microservice template Kubernetes teams deploy on purpose

> podinfo is a small Go web app that CNCF projects use as a test target for Kubernetes delivery. It installs with Helm, Timoni or Kustomize, and its value is in the failure modes it can reproduce on demand.

**stefanprodan/podinfo** — Go microservice template for Kubernetes

- Repository: https://github.com/stefanprodan/podinfo
- Stars: 6,008 · Forks: 1,890
- Language: Go
- License: Apache-2.0
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/stefanprodan-podinfo

## What podinfo is for, and who actually runs it

The README describes podinfo as "a tiny web application made with Go that showcases best practices of running microservices in Kubernetes." That sentence is the whole product. It is not a framework you build on and not a library you import. It is a running service with a deliberately wide surface: HTTP endpoints, a gRPC service, a web UI, Prometheus metrics, OpenTelemetry traces and logs, and a set of control endpoints that let you break it on purpose.

The audience is narrower than the description suggests. The README states that podinfo is used by CNCF projects including Flux and Flagger for end-to-end testing and workshops. That is the real use case. If you maintain a delivery tool, a service mesh, an ingress controller or a platform template, you need a workload that behaves predictably and can be made to misbehave on command. podinfo is that workload. If you are writing a business application in Go, the repository is worth reading as a reference for structure (cmd/, pkg/, kustomize/, charts/, timoni/) but it is not the skeleton you fork.

## The endpoints that make podinfo useful for testing

Most demo apps give you a hello world and a health check. podinfo exposes a control plane over itself. The README lists POST /readyz/enable and POST /readyz/disable, which tell the Kubernetes load balancer whether this instance should receive traffic. GET /status/{code} returns whatever status code you ask for. GET /delay/{seconds} waits before responding. GET /panic crashes the process with exit code 255.

The fault injection endpoints are the part worth reading twice. POST /fault_injection/enable makes the instance respond with HTTP 500 to all application endpoints, while probes, metrics, pprof and the /fault_injection/* control endpoints stay healthy. The README says this is useful for testing client-side circuit breakers and outlier detection against a single sick replica. That is a precise, well-scoped design decision: the pod stays Ready from Kubernetes' point of view while failing every real request, which is exactly the condition that trips mesh-level outlier detection and client retry logic. GET /fault_injection/status reports whether injection is on.

Alongside those, GET /env returns environment variables as a JSON array, GET /headers returns request headers, GET /configs returns configmaps and secrets mounted in the config volume, and GET /ws/echo echoes over websockets. The gRPC side mirrors much of this, including a PanicService that crashes the process with gRPC status code 1 CANCELLED.

## Installing podinfo with Helm, Timoni or Kustomize

The README states that the minimum required Kubernetes version is v1.23. Three installers are documented: Timoni, Helm and Kustomize, plus a plain Docker run for local checks.

Helm is the path most readers will take. The repository is added as a Helm repo, then a frontend release is installed into a test namespace with two replicas and a backend URL, followed by helm test.

```bash
helm repo add podinfo https://stefanprodan.github.io/podinfo

helm upgrade --install --wait frontend \
--namespace test \
--set replicaCount=2 \
--set backend=http://backend-podinfo:9898/echo \
podinfo/podinfo

helm test frontend --namespace test
```

The --wait flag blocks until the release is ready, and helm test runs the chart's test hook against the running release. The same chart is also published as an OCI artifact, which avoids the repo add step entirely:

```bash
helm upgrade --install --wait podinfo --namespace default \
oci://ghcr.io/stefanprodan/charts/podinfo
```

If you prefer to keep manifests in Git rather than in a chart, Kustomize is a single command against the repository path:

```bash
kubectl apply -k github.com/stefanprodan/podinfo//kustomize
```

For a local check without a cluster, the README gives a Docker one-liner that publishes port 9898:

```bash
docker run -dp 9898:9898 stefanprodan/podinfo
```

After that, GET / prints runtime information and GET /version prints the podinfo version and git commit hash. The Swagger UI is served at /swagger/index.html on the podinfo host. The README does not document a rollback procedure for any of these installers, so plan your own.

## Where podinfo stops being the right tool

The fault injection endpoints are a loaded gun. POST /fault_injection/enable turns every application endpoint into a 500 while leaving probes healthy, which means Kubernetes will not restart or evict the pod and no readiness gate will catch it. Anything that depends on that instance keeps failing until someone calls POST /fault_injection/disable. There is no documented authentication on those endpoints in the README, and no documented timeout after which injection expires. If you deploy podinfo into a shared cluster, anything that can reach the pod can disable it for real users of whatever depends on it.

GET /panic and the gRPC PanicService crash the process outright. That is the point, but it also means podinfo is a poor choice as a long-lived shared service.

The stateful endpoints have their own constraints. POST /store writes posted content to disk at /data/hash and GET /store/{hash} reads it back. The README does not describe any eviction, size limit or cleanup for that directory, so a pod that is written to repeatedly will grow its writable layer until the node reclaims it. The /cache endpoints require Redis, and the Helm example shows redis.enabled=true as an opt-in value rather than a default. If you enable Redis you now have a second workload to run and monitor.

Finally, podinfo is a template, not a foundation. Its dependencies, listed in go.mod, include gorilla/mux, viper, zap, the Prometheus client and a stack of OpenTelemetry packages. Copying that into a product means inheriting all of it, plus the demo endpoints, plus the UI directory shipped into the image by the Dockerfile. The repository does not present a stripped-down variant for that purpose.

## podinfo against httpbin and plain nginx

The obvious alternative for an echo target is httpbin, and the difference is architectural rather than cosmetic. httpbin is a request-inspection service: you send it a request and it tells you what it saw. It has no opinion about Kubernetes. It does not expose readiness and liveness endpoints shaped for kubelet probes, it does not ship a Helm chart, a Kustomize overlay or a Timoni module, and it does not emit Prometheus metrics or OpenTelemetry traces.

podinfo inverts that. Its HTTP surface exists partly to be inspected, but the parts that matter for platform work are the ones tied to the cluster lifecycle: /healthz for liveness, /readyz for readiness, /readyz/enable and /readyz/disable to move an instance in and out of the load balancer, /metrics for scraping, and the fault injection controls that let a single replica fail without Kubernetes noticing. Running nginx as a test workload gives you a process that responds; it gives you nothing to fail on demand and nothing to scrape.

The trade-off is that httpbin is a general-purpose tool you can point at any HTTP client, while podinfo is a Kubernetes-shaped one. If your test does not involve a cluster, podinfo's cluster-facing endpoints are dead weight.

## Maintenance, releases and what the Apache-2.0 licence means here

The repository is not archived, and the last push was on 2026-09-21. Releases are frequent and versioned: 6.15.0 on 2026-08-31, 6.14.1 on 2026-07-22, 6.14.0 on 2026-06-18. The project tracks current Go (go.mod declares go 1.27.0) and current Kubernetes APIs, and the build pipeline described in the README covers multi-arch images via Docker buildx, image signing with Sigstore cosign, SBOMs and SLSA provenance embedded in the image, and CVE scanning with govulncheck. There are also .cosign/ and .notation/ directories at the repository root, which suggests both signing systems are in use.

The upgrade cost is low if you consume podinfo as a deployed workload, because the chart and the OCI artifact are versioned and a Helm upgrade is a single command. It is higher if you forked the code, since you inherit the dependency set in go.mod and the release cadence of the upstream project.

podinfo is licensed under Apache-2.0. That is a permissive licence that generally allows commercial use, modification and redistribution provided the licence and notices are preserved and any modified files are marked. It also includes an explicit patent grant. This is a description of the licence text, not legal advice; if you are embedding podinfo or its code in a product, have your own counsel review the NOTICE and attribution requirements.

## Conclusion

Adopt podinfo when you need a known-good workload to exercise Helm releases, ingress, probes, service mesh traffic splitting, autoscaling or progressive delivery, and when you want a reference for how a Go service should expose health, metrics and traces. Do not adopt it as a starting point for a product you intend to ship, and do not treat it as a general-purpose HTTP echo server for production load. Verify first that your cluster meets the stated minimum of Kubernetes v1.23, that you know which installer you want (Timoni, Helm or Kustomize), and that you have decided whether the Redis-backed /cache endpoints and the /store disk writes are part of your test plan, because those two features change what the pod needs at runtime.

## FAQ

### What is podinfo?

podinfo is a small web application written in Go that demonstrates how to run a microservice on Kubernetes. The README describes it as a showcase of best practices, and notes it is used by CNCF projects such as Flux and Flagger for end-to-end testing and workshops.

### How do I install podinfo with Helm?

Add the chart repository with helm repo add podinfo https://stefanprodan.github.io/podinfo, then run helm upgrade --install --wait with the namespace, replica count and backend values you want. The chart is also published as an OCI artifact at oci://ghcr.io/stefanprodan/charts/podinfo.

### What Kubernetes version does podinfo need?

The README states that the minimum required version to install podinfo on Kubernetes is v1.23.

### What container image does podinfo use?

The README's Docker example runs stefanprodan/podinfo and publishes port 9898. The Dockerfile builds the podinfo and podcli binaries from source and copies the ui directory into the final Alpine image.

## Sources

- [Issues](https://github.com/stefanprodan/podinfo/issues)
- [License: Apache-2.0](https://github.com/stefanprodan/podinfo/blob/master/LICENSE)
- [README](https://github.com/stefanprodan/podinfo/blob/master/README.md)
- [Releases](https://github.com/stefanprodan/podinfo/releases)
- [stefanprodan/podinfo on GitHub](https://github.com/stefanprodan/podinfo)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/stefanprodan-podinfo
