Skip to content
Talk to our solutions team

Operations

Local HTTP-only loop:

Terminal window
gateway.svc config generate quickstart > .gateway.yaml
gateway.svc config generate spa-http -d config/
mkdir -p public && echo '<h1>hello</h1>' > public/index.html
gateway.svc -f .gateway.yaml -L debug
curl http://localhost:8443/

Production: start from the bootstrap profile (port 443, zerotrust: true, cert flags), keep routing in config.router.dir or on config.svc.

Run flags: -f/--config, -p/--port, -l/--log, -L/--loglevel, --sid, --datacenter, --cluster, --zerotrust, --svccert/--svckey/--rootca, --jwt_public_key, --config_url/--config_apikey, --servicediscovery_url/--servicediscovery_apikey.

The platform supervisor manages it as service gateway with default state up.

Routing config reloads without restart, from either source:

  • Local dir — recursive filesystem watch; any write/create/remove/rename triggers a debounced reload.
  • Remote — config.svc pushes over SSE.

Reload semantics:

  • The update is overlaid onto the last-known-good config, so a routing-only push can never wipe listener/boot keys.
  • On reload failure the previous config is re-applied; if that fails too, the process exits — the supervisor restarts it clean.
  • In-flight requests finish on the old configuration.
  • Static router config cannot change at runtime: entrypoints, ACME resolvers, and provider settings apply at boot only — changing them requires a restart. Everything in the routing plane (domainmaps, backends, endpoints, routes, staticpaths, LB profiles, passthrough dynamic config) is hot.

Backend server lists additionally update live via the service-discovery watcher (default 5s poll) without any config push.

  • Metrics listener (kisaimetrics, default 127.0.0.1:8088): Prometheus /metrics and Go pprof /debug/pprof/*. There is no health endpoint on the data plane — probe a route or the metrics listener.
  • Logslog: stdout or fluentd host:port. loglevel controls the gateway; router.loglevel independently dials the embedded router’s verbosity.
  • Access logs / tracking — an anonymous-tracker cookie and access-log events publish asynchronously (fire-and-forget) to configured endpoints; disabled on internal traffic; non-fatal when unset.
  • Dashboard — expose the router dashboard only through a normal, kisai-auth-gated route (dashboard example). The insecure API mode is a protected key and rejected at boot.
SymptomCause / action
Every request on a domain → 400Domain missing from all domainmaps — or domains: written as a scalar instead of a list (caught with a targeted error at load)
Nothing matches behind another proxyThe fronting proxy sends its own Host (e.g. localhost); add its IP to the entrypoint’s trustedips so X-Forwarded-Host is honored
Boot fails parsing routing filesThey’re in config.path instead of config.router.dir
Reload rejectedDuplicate names / unresolved references / protected passthrough paths / unknown certresolver — the error names the offender; last-known-good stays live
Browser shows a self-signed certACME issuance failed: check the certresolver is referenced by the route, ACME logs, :80 reachability for HTTP-01, and that acme.json is writable
Boot error “internal.port required”Legacy listener mode needs internal.port, or switch to an explicit entrypoints: list
TCP/UDP routes skip tenant headersL4 routes bypass the HTTP middleware chain by design — no CPET attribution