Status Page For Arcane Neko
This repository has been archived on 2026-07-16. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
  • JavaScript 78.1%
  • CSS 21.5%
  • HTML 0.4%
Find a file
2026-07-16 18:51:28 +00:00
backend document RUN_WORKERS worker modes and add PM2 ecosystem config 2026-06-15 22:23:40 +01:00
frontend Make admin section headers consistent and improve sidebar brand 2026-06-15 22:23:40 +01:00
scripts Fix endpoints freezing for check intervals over 59 seconds, Replace per-endpoint cron with setInterval, which handles arbitrary second intervals precisely and Add NeoStatus footer and single-source app version and rebrand 2026-06-13 23:43:49 +01:00
.gitignore Add configurable branding and refresh admin visuals 2026-06-15 22:23:40 +01:00
ecosystem.config.js document RUN_WORKERS worker modes and add PM2 ecosystem config 2026-06-15 22:23:40 +01:00
LICENSE Version 0.4 2026-04-16 23:08:23 +01:00
package.json Add configurable branding and refresh admin visuals 2026-06-15 22:23:40 +01:00
README.md Update README.md 2026-07-16 18:51:28 +00:00

NeoStatus

A self-hosted, real-time status page for monitoring your services, APIs, and infrastructure.

MIT License Node.js 24 LTS SQLite


Warning

This project is no longer in development, the cost of hosting, not having enough time and changes in my life, i decided to stop development and focus on things that i really care about. I going to leave the code up if anyone comes accross it and decides it's useful for them. no support will be given and NeoNeko has change it's focused.

NeoStatus

A free and open source status page you can self-host to monitor uptime, track incidents, and show your users a clean, real-time view of your services. No external database required, everything runs on SQLite.

Features

Real-time monitoring - monitor HTTP/HTTPS endpoints, TCP ports, and ICMP ping with customisable check intervals from 10 seconds to 1 hour.

Live status updates - WebSocket-powered real-time updates pushed to the public status page and admin dashboard as checks complete.

Admin dashboard - add, edit and remove endpoints, manage incidents, configure site settings, manage users, and generate API keys from a single panel.

Public status page - a clean, responsive page showing current status, response times, uptime stats, heatmaps, active incidents, and overall system health.

Incident management - create, update, and resolve incidents with severity levels, link them to affected endpoints, and write post-mortems.

Scheduled maintenance - schedule maintenance windows for endpoints to pause monitoring and display notice to visitors.

Uptime tracking - automatic uptime percentage calculation with SLA tracking over configurable time periods, plus jitter and packet loss metrics for ping checks.

Role-based access - admin and viewer roles with enforced permissions on all protected routes.

Email notifications - SMTP-based notifications with per-user preferences. Subscribe to all endpoints or specific categories. Get notified on downtime, recovery, degradation, or incidents.

API access - generate API keys for programmatic access to your status data. Rate-limited public API with status.json, summary, components, and incidents endpoints.

Custom branding - rename your status page, customize the public URL, and configure SMTP for outgoing notifications.

Zero external dependencies - SQLite database, no Redis or Postgres required. Just Node.js.

Note

See it in action here: https://status.neoneko.org

Note

This project is actively developed. Slack/Discord notifications, detailed analytics, and more are planned for future releases.

Requirements

  • Node.js 24 LTS or newer
  • A Linux, macOS, or Windows machine

Quick Start

1. Clone and install

git clone https://git.neoneko.org/NeoNeko/NeoStatus
cd NeoStatus

# Install all dependencies (root, backend, and frontend)
npm run install-all

2. Configure

cp backend/.env.example backend/.env

Edit backend/.env and change the JWT secret to a strong random value:

PORT=5000
NODE_ENV=production
JWT_SECRET=replace_with_a_strong_random_string
DATABASE_PATH=../data/status.db
FRONTEND_URL=https://status.example.com

# Background workers (monitoring, maintenance scheduler, webhook retries).
# Leave unset/true to run them inside the API process (simplest).
# Set to false ONLY if you run a separate worker process (see deployment below).
RUN_WORKERS=true
# Required only when RUN_WORKERS=false must match on the API and the worker
# so the worker can forward realtime events to the API.
# WORKER_SECRET=replace_with_a_shared_random_string

Important

Never deploy with the default JWT secret. Generate one with openssl rand -hex 64 or similar.

Important

The background worker drives endpoint monitoring, the scheduled-maintenance start/end webhooks, and webhook delivery retries. If it isn't running, the public page goes stale and maintenance webhooks never fire. Make sure your chosen mode below actually starts it.

3. Run

Development (runs React dev server + backend with hot reload):

npm run dev

Production (builds frontend, serves everything from the backend):

# Build the frontend
npm run build

# Start the server
npm start

Everything runs on a single port in production:

URL
Status page http://localhost:5000
Admin panel http://localhost:5000/admin
API http://localhost:5000/api

On first launch you'll be guided through a setup wizard to create your admin account and configure site settings.

Public API

NeoStatus exposes a free, rate-limited (60 req/min) public API for integration:

Endpoint Description
/api/v1/status.json Full status dump (primary integration)
/api/v1/summary Lightweight summary (page name + overall status)
/api/v1/components All monitored components
/api/v1/incidents Current and past incidents
/api/v1/scheduled-maintenances Upcoming scheduled maintenance

You can enrich responses by passing an API key via the X-API-Key header.

Production Deployment

Worker modes

The background worker (endpoint monitoring, scheduled-maintenance start/end scheduler, and webhook delivery retries) can run in one of two modes, controlled by RUN_WORKERS in backend/.env:

Mode RUN_WORKERS What runs Use when
In-process (recommended) true or unset One process serves the API and runs the workers Single server / VM simplest, nothing to forget
Split false API process + a separate worker process You scale the API separately, run multiple API instances, or want the worker isolated

Warning

In split mode, RUN_WORKERS=false makes the API start without any workers. You must start the worker process separately, or monitoring and maintenance webhooks silently never run. Manage both with the PM2 ecosystem file below so you can't start one without the other.

With RUN_WORKERS=true (or unset), a single process does everything:

# Install PM2 globally
npm install -g pm2

# Build the frontend first
npm run build

# Start the app (API + workers in one process)
pm2 start "npm start" --name neostatus

# Auto-start on reboot
pm2 startup
pm2 save

# View logs
pm2 logs neostatus

Running with PM2, split mode (separate worker)

With RUN_WORKERS=false, run the API and the worker as two PM2 apps. The repo ships an ecosystem.config.js that defines both, so a single command always brings them up together:

npm install -g pm2
npm run build

# Set these in backend/.env:
#   RUN_WORKERS=false
#   WORKER_SECRET=<same value used by both processes>

# Start BOTH the API and the worker
pm2 start ecosystem.config.js

# Auto-start on reboot
pm2 startup
pm2 save

# Verify both are online
pm2 ls            # expect: neostatus (API) AND neostatus-worker
pm2 logs neostatus-worker

Day-to-day, always use pm2 start ecosystem.config.js / pm2 restart ecosystem.config.js so the worker is never left behind. Starting only the API (e.g. pm2 start neostatus) will leave monitoring and maintenance webhooks dead.

Tip

Not sure if the worker is running? If the public page stops updating or scheduled maintenance never fires its webhook, check pm2 ls the worker process should be online, and pm2 logs neostatus-worker should show ✓ NeoStatus worker running.

Using a Reverse Proxy (Nginx)

Since everything runs on port 5000 in production, the Nginx config is straightforward:

server {
    listen 80;
    server_name status.example.com;

    location / {
        proxy_pass http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_buffering off;
    }
}

Tip

Use Certbot to add HTTPS with a free Let's Encrypt certificate. Update FRONTEND_URL in your .env to match your domain.

Troubleshooting

Port already in use
lsof -i :5000
lsof -i :3000
kill -9 <PID>
Database issues

Delete the database to reset (this loses all data):

rm data/status.db
npm start

The database will be recreated automatically on startup.

Public page is stale / maintenance webhooks never fire

These are all driven by the background worker. If it isn't running, endpoint checks stop updating, scheduled maintenance never transitions, and its maintenance.start / maintenance.end webhooks never fire even though incident webhooks (triggered by admin actions on the API) still work.

  • In-process mode (RUN_WORKERS=true/unset): restart the app pm2 restart neostatus.
  • Split mode (RUN_WORKERS=false): the worker is a separate process. Check it's up with pm2 ls and start both with pm2 start ecosystem.config.js. Restarting only the API does not start the worker.

Confirm the worker is alive: pm2 logs neostatus-worker should show ✓ NeoStatus worker running, and new endpoint checks should appear shortly after startup.

WebSocket not connecting

Make sure FRONTEND_URL in backend/.env matches your actual frontend URL. If using a reverse proxy, ensure the /socket.io path is proxied correctly.

Ping checks not working

Ping checks require elevated privileges. On Linux, you may need to set the correct capability:

sudo setcap cap_net_raw+ep $(which node)

Or run the backend as root (not recommended for production).

License

MIT


Made with care for anyone who needs a simple, self-hosted status page.