Build And Deploy
Control Plane
Expose liveness, readiness, metrics, and Go diagnostics outside application routes.
Enable probes in app config
Add an empty control-plane config when the app should expose framework-owned operational endpoints on the same handler as the app:
return lazyapp.New(lazyapp.Config{
Name: "sample_app",
Drawer: Draw,
Public: app.Public,
Views: app.Views,
Context: Context,
ControlPlane: lazycontrolplane.Config{},
})
The empty config exposes:
GET /livez
GET /readyz
Control-plane routes are checked before application routes. If the app also
draws /livez, the control-plane route wins.
Use a separate address
ListenAndServe activates the default control plane when
CONTROL_PLANE_ADDR is set:
ADDR=0.0.0.0:8080 CONTROL_PLANE_ADDR=127.0.0.1:9090 ./app
When CONTROL_PLANE_ADDR differs from the app address, ListenAndServe starts
a second HTTP server for the control plane. The public app server then serves
only application traffic.
If CONTROL_PLANE_ADDR matches ADDR, PORT, or the default :3000, GoLazy
mounts the control plane into the app server instead of trying to bind the same
port twice:
CONTROL_PLANE_ADDR=3000 ./app
Add readiness checks
Readiness checks receive the request context and return an error when the app is not ready:
ControlPlane: lazycontrolplane.Config{
Readiness: []lazycontrolplane.ReadinessCheck{{
Name: "database",
Check: func(ctx context.Context) error {
return db.PingContext(ctx)
},
}},
},
/readyz returns 503 Service Unavailable when a check fails.
Attach metrics and pprof
Metrics are opt-in:
ControlPlane: lazycontrolplane.Config{
Metrics: metricsHandler,
},
That registers GET /metrics. GoLazy does not add a Prometheus dependency for
you; pass a handler from the exporter you choose.
Go diagnostics are also opt-in:
ControlPlane: lazycontrolplane.Config{
Pprof: true,
},
That registers /debug/pprof/ and the standard pprof subpaths. Prefer a
separate CONTROL_PLANE_ADDR before enabling diagnostics in production.
Serve manually
If you need a custom server lifecycle, instantiate the control plane yourself:
plane := lazycontrolplane.New(lazycontrolplane.Config{})
server := &http.Server{
Addr: "127.0.0.1:9090",
Handler: plane,
}
When you manage the server manually, lazyapp.ListenAndServe is not responsible
for starting that control-plane server.