Analytics cookies only (Google Analytics, PostHog). No ad networks, no cross-site tracking. See our privacy policy.
Self-host Kener
updated Oct 2026deployed by usprices checked · Jul 2026Install verified on Ubuntu 26.04 · Oct 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →
A status page system: public pages fed by uptime monitors, with incidents, maintenance windows, alerting and role-based team access, so your users can see what is up and what is not. MIT-licensed, built with Node.js and Svelte; it needs Redis for its queues, cache and scheduler and stores its own data in SQLite by default (PostgreSQL or MySQL via DATABASE_URL).
Runs on a VPS from $6/mo (Kamatera 2GB, 2 GB RAM) · prices checked Sep 2026
Our recommendation
Pick Kener when the thing you need is a status page your users can read, not another alerting console: public pages fed by API and website monitors, incidents, maintenance windows, grace periods, subscriber alerting, internationalization and role-based team access with admin, editor and member roles. It is MIT-licensed, built with Node.js and Svelte, and requires Redis for its BullMQ queues, cache and scheduler; its own data goes to SQLite in a mounted `database` directory by default, or PostgreSQL or MySQL through `DATABASE_URL`. Our snippet is the repo's compose file trimmed to Redis plus Kener with a generated `KENER_SECRET_KEY`. Upstream's Redis setup page sizes the app at 512 MB minimum and 1 GB recommended, plus 128 to 256 MB for Redis, so our 512 MB floor is the documented minimum. The catalog's Uptime Kuma, Gatus, Checkmate and Healthchecks are monitoring-first, with status pages as a feature; Kener reverses that, and Beszel, Glances and Zabbix are host-metrics tools doing a different job entirely.
What you need
Any VPS with at least 512 MB of RAM
A domain you control — most self-hosted setups need HTTPS in front of them
Paid link — we earn a commission if you shop through it.
Install
Run these commands on your server:
# Kener — status page with uptime monitors, incidents and maintenance windows — based on the docker-compose.yml in the Kener repo and its Deployment docs, pinned to v4.1.7echo "KENER_SECRET_KEY=$(openssl rand -hex 32)" > .envcat > docker-compose.yml <<'EOF'services: redis: image: redis:7-alpine restart: unless-stopped volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 kener: image: rajnandan1/kener:v4.1.7 restart: unless-stopped environment: KENER_SECRET_KEY: ${KENER_SECRET_KEY} ORIGIN: http://SERVER_IP:3000 REDIS_URL: redis://redis:6379 ports: - 3000:3000 volumes: - kener_data:/app/database depends_on: redis: condition: service_healthyvolumes: redis_data: kener_data:EOFdocker compose up -d# → http://SERVER_IP:3000 — ORIGIN must be the public URL people use (replace SERVER_IP above, or sign-in form posts fail the CSRF check)
Kener's deployment docs and compose file flag these before you point users at it:
non-negotiableORIGIN is required and must be the public URL with no trailing slash, because it drives CSRF protection; our compose uses the http://SERVER_IP:3000 placeholder, so replace it with the address people will use before anyone signs in, and set the Site URL in the dashboard, which upstream calls very important. For a /status subpath, ORIGIN stays the domain root, KENER_BASE_PATH carries the path and you use the -status image.
non-negotiableBy default everything is a SQLite file in the /app/database volume (kener_data in our compose, mirroring upstream's named volume: the image runs as the non-root node user, so a host-owned bind mount there fails with an unopenable database), with Redis in its own volume; back that volume up, or move to PostgreSQL or MySQL via DATABASE_URL. The current major release differs from the previous one, and upstream points existing users at a migration guide rather than a plain image swap.
non-negotiableUpstream's compose runs rajnandan1/kener:latest; versioned tags such as v4.x.y, -alpine and -status exist, and our snippet pins one. The /healthcheck endpoint always returns HTTP 200 (the body says degraded when the database or Redis is down); ?strict=1 returns 503 instead, which upstream warns not to use for a restart-on-failure healthcheck, since restarting Kener cannot fix a dead database.
non-negotiablePort 3000 is plain HTTP, so terminate TLS at a reverse proxy, which upstream documents separately. KENER_SECRET_KEY must be a strong random string; our snippet generates one. Inviting teammates creates an inactive account with an empty password that the invitee sets on the invitation page, and alert email needs the SMTP or Resend variables from the deployment docs.