Lightweight, self-hosted uptime monitoring and status page. Built with Node.js and SQLite.
Zero dependencies beyond Node.js. No Docker required. No external database. Just npm start.
- HTTP/HTTPS Monitoring - Check endpoints at 1-30 minute intervals
- Keyword Checks - Verify response body contains (or doesn't contain) specific text
- SSL Certificate Monitoring - Track certificate expiry with 14-day warnings
- Public Status Page - Share uptime with your users via a clean, branded status page
- Dashboard - Real-time overview with uptime %, response times, and incident history
- Monitor Detail View - Response time charts, percentile breakdown (p50/p95/p99)
- Tags & Filtering - Organize monitors with tags, filter the dashboard
- Pause/Resume - Temporarily disable monitoring without deleting configuration
- Webhook Notifications - Instant alerts to Slack, Discord, or any webhook URL
- Notification Channels - Multiple notification endpoints with extensible architecture
- API Key Authentication - Optional auth for admin API endpoints
- Rate Limiting - Built-in protection against API abuse
- Export/Import - Backup and restore monitor configurations as JSON
- Data Retention - Automatic cleanup of old check data (30-day default)
- Docker Ready - Dockerfile and docker-compose.yml included
- SQLite Storage - Zero-config database, WAL mode for performance
git clone https://github.com/yourusername/zerostatus.git
cd zerostatus
npm install
npm startOpen http://localhost:3000 to access the dashboard.
docker compose up -dOr build manually:
docker build -t zerostatus .
docker run -d -p 3000:3000 -v zerostatus-data:/data zerostatusEnvironment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Server port |
ZEROSTATUS_DATA_DIR |
./data |
Database storage directory |
| URL | Description |
|---|---|
/ |
Admin dashboard |
/status |
Public status page |
/monitor?id=X |
Monitor detail view |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/monitors |
List all monitors (supports ?tag= filter) |
| GET | /api/monitors/:id |
Get monitor with status |
| POST | /api/monitors |
Create a monitor |
| PUT | /api/monitors/:id |
Update a monitor |
| DELETE | /api/monitors/:id |
Delete a monitor |
| GET | /api/monitors/:id/checks |
Check history (supports ?limit=) |
| GET | /api/monitors/:id/percentiles |
Response time percentiles (?period=) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/health |
Health check |
| GET | /api/incidents |
Recent incidents |
| GET | /api/settings |
Get settings |
| PUT | /api/settings |
Update settings |
| GET | /api/notifications |
List notification channels |
| POST | /api/notifications |
Create notification channel |
| DELETE | /api/notifications/:id |
Delete notification channel |
| GET | /api/export |
Export all configuration |
| POST | /api/import |
Import configuration |
| POST | /api/admin/cleanup |
Manual data cleanup |
curl -X POST http://localhost:3000/api/monitors \
-H "Content-Type: application/json" \
-d '{
"name": "My Website",
"url": "https://example.com",
"interval_seconds": 300,
"tags": ["production", "web"],
"keyword": "Welcome"
}'API key auth is disabled by default. To enable:
curl -X PUT http://localhost:3000/api/settings \
-H "Content-Type: application/json" \
-d '{"auth_enabled": "true"}'Then use the auto-generated API key (shown in server logs on first run):
curl -H "Authorization: Bearer zs_your_key_here" \
http://localhost:3000/api/monitors- Runtime: Node.js 18+
- Framework: Express.js
- Database: SQLite (better-sqlite3)
- Frontend: Vanilla HTML/CSS/JS (no build step)
MIT