Web console for NATS JetStream: streams, consumers, messages, KV, object store
690
Web console for NATS JetStream, in the spirit of Conduktor for Kafka: streams, consumers with lag,
message browser, KV, object store, live tail, publish/request and connections. A single Go binary with
the React UI embedded, shipped as a small distroless image for linux/amd64 and linux/arm64.
Source, issues and releases: https://gitlab.com/amir-amirov/nats-console
Point the console at one NATS server, no config file needed:
docker run --rm -p 127.0.0.1:8080:8080 \
-e NATS_URL=nats://host.docker.internal:4222 \
-e NATS_MONITORING_URL=http://host.docker.internal:8222 \
amiramirov/nats-console:latest
Open http://127.0.0.1:8080.
NATS_MONITORING_URL is optional; without it the Overview server stats and Connections pages are empty.127.0.0.1 is the container itself. Use host.docker.internal for a server on your
machine (on Linux add --add-host=host.docker.internal:host-gateway), or the service name when NATS
runs in the same Docker network.127.0.0.1 only. See Authentication before exposing it.A config file lets you add several clusters, credentials, read-only mode and login.
# config.yaml
sampleInterval: 10s # how often stream/consumer metrics are sampled for charts
retention: 1h # how long samples are kept in memory
clusters:
- id: local
name: Local
url: nats://host.docker.internal:4222
monitoringUrl: http://host.docker.internal:8222
- id: prod
name: Production
url: nats://nats.example:4222
monitoringUrl: http://nats.example:8222
readOnly: true # browse only: no publish, purge, delete, KV put, pause
color: "#dc2626" # accent color, so you always see which cluster you are on
auth:
credsFile: /secrets/console.creds # or user/password, or token: ${NATS_TOKEN}
auth:
mode: none # none | basic | oidc | proxy
docker run --rm -p 127.0.0.1:8080:8080 \
-v "$PWD/config.yaml:/config.yaml:ro" \
-v "$PWD/console.creds:/secrets/console.creds:ro" \
-e NATS_TOKEN \
amiramirov/nats-console:latest -config /config.yaml
${VAR} values in the config are expanded from the environment, so keep secrets in env vars or mounted
files, not in the YAML. The full annotated example is
config.example.yaml.
services:
nats:
image: nats:2
command: ["-js", "-m", "8222"]
nats-console:
image: amiramirov/nats-console:latest
environment:
NATS_URL: nats://nats:4222
NATS_MONITORING_URL: http://nats:8222
ports:
- "127.0.0.1:8080:8080"
depends_on: [nats]
Set in the auth section of the config:
| Mode | Use when |
|---|---|
none (default) | local use, port published on 127.0.0.1 only |
basic | a few local accounts, passwords stored as bcrypt hashes |
oidc | single sign-on with GitLab, Keycloak, Google, Azure AD; group and e-mail domain allow-lists |
proxy | behind oauth2-proxy / Pomerium; identity headers accepted only from trustedProxies |
Roles: admin can publish, purge, delete, edit and pause; viewer can only browse. A cluster marked
readOnly stays read-only for admins too. Every change is logged as an audit line with the user name.
Basic auth example:
# hash a password (type it, press Enter)
docker run --rm -i amiramirov/nats-console:latest hash-password
auth:
mode: basic
sessionSecret: ${NATS_CONSOLE_SESSION_SECRET} # openssl rand -hex 32
users:
- username: admin
passwordHash: "$2a$12$..."
role: admin
- username: support
passwordHash: "$2a$12$..."
role: viewer
docker run -d --name nats-console -p 8080:8080 \
-v "$PWD/config.yaml:/config.yaml:ro" \
-e NATS_CONSOLE_SESSION_SECRET="$(openssl rand -hex 32)" \
amiramirov/nats-console:latest -config /config.yaml
For OIDC and proxy settings see the comments in config.example.yaml. Put the console behind HTTPS when it is reachable from outside your machine.
| Setting | Description |
|---|---|
port 8080 | HTTP UI and API; the image listens on 0.0.0.0:8080 |
-config /path.yaml | config file; or env NATS_CONSOLE_CONFIG |
NATS_URL, NATS_MONITORING_URL | single cluster when no config file is given (default nats://127.0.0.1:4222) |
-listen host:port | change the listen address |
-debug | debug logging |
/healthz | always public, for probes; the image has a built-in HEALTHCHECK |
version | docker run --rm amiramirov/nats-console version |
hash-password | bcrypt hash for basic auth |
The image is distroless and runs as a non-root user. Mounted config and creds files must be readable by
it (chmod 644, or mount them :ro from a readable location).
| Tag | Meaning |
|---|---|
latest | latest stable release |
X.Y.Z, X.Y, X | pinned releases, e.g. 0.1.2, 0.1, 0 |
X.Y.Z-rc.N | release candidates |
Pin a version (amiramirov/nats-console:0.1) for anything you do not want to change under you.
| Area | What you get |
|---|---|
| Overview | streams/consumers/messages/storage KPIs, ingest throughput, consumers needing attention, largest streams, server stats |
| Streams | search and filter, create, edit (form or JSON), purge (all, by subject, keep N), delete |
| Stream detail | message browser, consumers, subjects with counts, metrics charts, limits/placement/raw config |
| Message browser | latest / earliest / from sequence / from time, subject filter with wildcards, paging, JSON / raw / hex payload, headers, republish, delete |
| Consumers | pending, unacked, redelivered, lag trend and health (stalled, redelivering, lagging, paused); pause/resume, delete |
| KV | buckets, keys, value viewer, revision history, put/delete/purge |
| Object store | buckets, objects, download, delete |
| Live tail | core subscription on any subject, streamed to the browser |
| Publish | core, JetStream with PubAck, or request/reply |
| Connections | connected clients with their subscriptions |
The message browser reads with STREAM.MSG.GET and never creates consumers, so it is safe on work-queue
streams and does not change delivery state.
Charts come from an in-process sampler; history starts when the console starts and is not persisted.
Content type
Image
Digest
sha256:0cb61a37f…
Size
5.1 MB
Last updated
3 days ago
docker pull amiramirov/nats-console