CrowdSec Web UI
A self-hosted dashboard for CrowdSec: investigate alerts, manage decisions, monitor runtime metrics, and send notifications from one responsive UI.
Features
| Area | Highlights |
|---|---|
| Dashboard | Alert and active-decision totals, attack map, drilldowns, top lists, shared quick filters, and simulation counts |
| Alerts | Searchable alert history, persistent count-aware quick filters, CrowdSec alert contexts, IP/AS/location details, event metadata, simulation labels, and configurable columns |
| Decisions | Active and expired decisions, persistent count-aware quick filters, duplicate hiding, manual bans, custom durations, reasons, and cleanup actions |
| Multi-instance | Several CrowdSec LAPIs, per-instance views, and a Combined scope for Dashboard, Alerts, and Decisions |
| Metrics | Optional Prometheus views for LAPI activity, bouncers, AppSec, parsers, latency, parsing time, and whitelists |
| Notifications | Alert, decision, CVE, availability, and update rules delivered through Email, Gotify, MQTT, ntfy, or Webhooks |
| Security | Initial administrator setup, password and TOTP login, passkeys, OIDC SSO, group roles, and instance-wide read-only mode |
| Localization | Arabic, Chinese, English, French, German, Hindi, Japanese, Portuguese, Russian, and Spanish |
| Experience | Unified search, dark/light themes, and responsive layouts |
Screenshots
Quick Start
You need a running CrowdSec LAPI. Connect the Web UI using either watcher password authentication or agent mTLS.
1. Register the Web UI
Watcher password
openssl rand -hex 32
docker exec crowdsec cscli machines add crowdsec-web-ui --password 'replace-with-generated-password' -f /dev/null
# For local installations
sudo cscli machines add crowdsec-web-ui --password 'replace-with-generated-password' -f /dev/null
Replace replace-with-generated-password with the value printed by openssl.
[!IMPORTANT] Keep
-f /dev/null. It registers the machine without overwriting the CrowdSec container's existing credentials file.
Agent mTLS
Configure LAPI TLS authentication and create a client certificate/key pair using the CrowdSec TLS authentication guide.
2. Start with Docker Compose
services:
crowdsec-web-ui:
image: ghcr.io/theduffman85/crowdsec-web-ui:latest
container_name: crowdsec_web_ui
ports:
- "3000:3000"
# For local CrowdSec instances
# extra_hosts:
# - "host.docker.internal:host-gateway"
environment:
CONFIG_INSTANCE_LAPI_URL: http://crowdsec:8080
# For local CrowdSec instances
# CONFIG_INSTANCE_LAPI_URL: http://host.docker.internal:8080
CONFIG_INSTANCE_LAPI_AUTH_USERNAME: crowdsec-web-ui
CONFIG_INSTANCE_LAPI_AUTH_PASSWORD: your-crowdsec-password
volumes:
- ./data:/app/data
restart: unless-stopped
A ready-to-use docker-compose.yml is included. Add the generated password, make sure the Web UI can reach CrowdSec on the same Docker network, then start it.
docker compose up -d
Open http://localhost:3000 and create the initial administrator account.
Docker Run Alternative
docker pull ghcr.io/theduffman85/crowdsec-web-ui:latest
mkdir -p data
docker run -d \
--name crowdsec_web_ui \
-p 3000:3000 \
-v $(pwd)/data:/app/data \
-e CONFIG_INSTANCE_LAPI_URL=http://crowdsec:8080 \
-e CONFIG_INSTANCE_LAPI_AUTH_USERNAME=crowdsec-web-ui \
-e CONFIG_INSTANCE_LAPI_AUTH_PASSWORD=your-crowdsec-password \
--network your_crowdsec_network \
ghcr.io/theduffman85/crowdsec-web-ui:latest
Current images use Node.js and do not have the former Bun/AVX-specific x64 limitation.
mTLS Compose Alternative
services:
crowdsec-web-ui:
image: ghcr.io/theduffman85/crowdsec-web-ui:latest
container_name: crowdsec_web_ui
ports:
- "3000:3000"
environment:
CONFIG_INSTANCE_LAPI_URL: https://crowdsec:8080
CONFIG_INSTANCE_LAPI_AUTH_TYPE: mtls
CONFIG_INSTANCE_LAPI_AUTH_CERT_FILE: /certs/agent.pem
CONFIG_INSTANCE_LAPI_AUTH_KEY_FILE: /certs/agent-key.pem
# CONFIG_INSTANCE_LAPI_TLS_CA_FILE: /certs/ca.pem
volumes:
- ./data:/app/data
- /path/on/host/agent.pem:/certs/agent.pem:ro
- /path/on/host/agent-key.pem:/certs/agent-key.pem:ro
# - /path/on/host/ca.pem:/certs/ca.pem:ro
restart: unless-stopped
Adjust the URL and certificate paths. Enable CONFIG_INSTANCE_LAPI_TLS_CA_FILE and its volume when LAPI uses a private CA.
[!CAUTION] Use HTTPS and a hardened reverse proxy for public deployments. Built-in authentication protects the UI and API, but TLS terminates outside the application. OIDC integrations include Authentik, Authelia, and Keycloak. Migrated installations that predate authentication remain unauthenticated until explicitly enabled.
Architecture
| Component | Implementation |
|---|---|
| Client | React, Vite, and Tailwind CSS; builds to dist/client |
| Server | Node.js and Hono; builds to dist/server |
| Storage | SQLite via better-sqlite3 under /app/data |
| CrowdSec | Watcher password or agent mTLS; delta refreshes and chunked historical synchronization |
| Container | Runs as the non-root node user |











