A minimal HTTP service intended for debugging orchestration behavior (e.g., Kubernetes liveness/readiness).
It exposes /healthz and /readyz which become healthy/ready only after a configurable startup delay.
Admin endpoints allow resetting probe state back to unhealthy/not-ready and re-applying the delay.
GET /healthz200 OKwhen health flag istrue503 Service Unavailablewhile health flag isfalse
GET /readyz200 OKwhen ready flag istrue503 Service Unavailablewhile ready flag isfalse
While not in the target state, the response includes retry_after_ms to indicate the remaining delay.
Security note: These endpoints are intentionally unauthenticated. Do not expose them publicly. If you run behind a load balancer or in a cluster, protect them (network policy, auth, or bind to localhost).
POST /admin/reset- Resets both health and ready to
falseand restarts the startup delay for both.
- Resets both health and ready to
POST /admin/health/reset- Resets health to
falseand restarts its delay.
- Resets health to
POST /admin/ready/reset- Resets ready to
falseand restarts its delay.
- Resets ready to
All configuration is done via environment variables.
| Variable | Default | Type | Description |
|---|---|---|---|
PORT |
8080 |
int | TCP port the server listens on. Valid range: 1..65535. |
STARTUP_DELAY |
30s |
duration | Delay applied to both /healthz and /readyz before they switch to the target state. |
SHUTDOWN_WAIT |
10s |
duration | Graceful shutdown timeout. |
READ_TIMEOUT |
15s |
duration | HTTP server read timeout. |
WRITE_TIMEOUT |
15s |
duration | HTTP server write timeout. |
IDLE_TIMEOUT |
60s |
duration | HTTP server idle timeout. |
MAX_BODY_BYTES |
1048576 (1 MiB) |
int64 | Maximum request body size enforced via http.MaxBytesReader. |
SERVICE_NAME |
probe-service |
string | Included in JSON responses and logs. |
LOG_LEVEL |
info |
string | Log level: debug, info, warn, error. Logs are JSON (via log/slog). |
STARTUP_DELAY, SHUTDOWN_WAIT, READ_TIMEOUT, WRITE_TIMEOUT, IDLE_TIMEOUT use Go duration format, e.g.:
250ms,5s,1m,2h
make all./bin/serverexport PORT=9090
export STARTUP_DELAY=5s
./bin/serverexport LOG_LEVEL=debug
./bin/serverAssuming default port 8080.
curl -sS localhost:8080/healthz | jq
curl -sS localhost:8080/readyz | jqsleep 30
curl -sS localhost:8080/healthz | jq
curl -sS localhost:8080/readyz | jqcurl -sS -X POST localhost:8080/admin/reset | jq
curl -sS localhost:8080/healthz | jq
curl -sS localhost:8080/readyz | jqcurl -sS -X POST localhost:8080/admin/ready/reset | jq
curl -sS localhost:8080/readyz | jqcurl -sS -X POST localhost:8080/admin/health/reset | jq
curl -sS localhost:8080/healthz | jqdocker run --rm -p 8080:8080 \
-e PORT=8080 \
-e STARTUP_DELAY=10s \
-e LOG_LEVEL=info \
probe-service:localdocker run --rm -p 9090:9090 \
-e PORT=9090 \
-e STARTUP_DELAY=3s \
probe-service:localExample container env and probes (adjust image/name as needed):
apiVersion: apps/v1
kind: Deployment
metadata:
name: probe-service
spec:
replicas: 1
selector:
matchLabels:
app: probe-service
template:
metadata:
labels:
app: probe-service
spec:
containers:
- name: probe-service
image: your-registry/probe-service:latest
env:
- name: PORT
value: "8080"
- name: STARTUP_DELAY
value: "30s"
- name: LOG_LEVEL
value: "info"
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /readyz
port: 8080
periodSeconds: 2
failureThreshold: 3
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 5
failureThreshold: 3