Ultra-lightweight web monitoring for Raspberry Pi
Track uptime, response times, and get instant alerts — all from a $35 computer
| Feature | Benefit |
|---|---|
| 🪶 Ultra-lightweight | Runs on Raspberry Pi 1B+ (512MB RAM) |
| 📊 Real-time Dashboard | CRT-style cyberpunk interface |
| 🔌 JSON API | Integrate with anything |
| 💾 Persistent Storage | SQLite keeps your history safe |
| ⚡ Zero Config | Works out of the box |
How does WebStatusPi compare to popular alternatives?
Runtime Performance (Docker benchmark: 5 URLs, 60s interval, 10 samples)
| Tool | RAM Usage | CPU Usage | Docker Image |
|---|---|---|---|
| WebStatusPi | 17 MB | 0.2% | 61 MB |
| Statping-ng | 30 MB | 0.5% | 58 MB |
| Uptime Kuma | 114 MB | 0.2% | 439 MB |
Installation Size on Raspberry Pi (native, no Docker)
| Tool | Install Size | Requires |
|---|---|---|
| WebStatusPi | ~1 MB | Nothing (uses system Python) |
| Statping-ng | ~58 MB | Go binary |
| Uptime Kuma | ~150 MB | Node.js runtime |
WebStatusPi leverages the Python already installed on Raspberry Pi OS. Run ./benchmark/benchmark.sh to reproduce the runtime benchmark.
Run this on your Raspberry Pi:
curl -sSL https://raw.githubusercontent.com/jmlweb/webstatuspi/main/install.sh | bashThe interactive installer will:
- Install dependencies and create a virtual environment
- Guide you through URL configuration
- Optionally set up auto-start on boot
That's it! Open http://<your-pi-ip>:8080 in your browser.
📦 Manual Installation
# Clone and install
git clone https://github.com/jmlweb/webstatuspi.git
cd webstatuspi
python3 -m venv venv
source venv/bin/activate
pip install .
# Configure
cp config.example.yaml config.yaml
# Edit config.yaml with your URLs
# Run
webstatuspi⚙️ Installer Options
# Interactive installation
./install.sh
# Non-interactive with defaults
./install.sh --non-interactive
# System-wide installation (with systemd service)
sudo ./install.sh --install-dir /opt/webstatuspi
# Update existing installation
./install.sh --update
# Uninstall
./install.sh --uninstall
Real-time status cards with latency and 24h uptime metrics. |
Click any card to see full check history with timestamps. |
Features:
- 🔄 Auto-refresh every 10 seconds
- 🟢🔴 Color-coded status indicators
- 📈 Response time graphs
- 🕹️ Retro CRT aesthetic with scanlines
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Web dashboard |
GET |
/status |
All URLs status |
GET |
/status/{name} |
Specific URL status |
GET |
/health |
Health check |
curl http://localhost:8080/status{
"urls": [
{
"name": "MY_SITE",
"url": "https://example.com",
"success_rate": 99.5,
"last_status": "success",
"last_status_code": 200
}
],
"summary": {
"total_urls": 1,
"overall_success_rate": 99.5
}
}Get instant notifications when URLs go down or recover. Integrate with Slack, Discord, PagerDuty, or any custom webhook endpoint.
Add to your config.yaml:
alerts:
webhooks:
- url: "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
enabled: true
on_failure: true # Alert when URL goes DOWN
on_recovery: true # Alert when URL comes back UP
cooldown_seconds: 300 # Minimum time between alerts (prevents spam)| Service | Webhook Type | Notes |
|---|---|---|
| Slack | Incoming Webhook | Configure in Apps & integrations |
| Discord | Webhook URL | Copy webhook URL from channel settings |
| Telegram | Bot API Webhook | Use with telegram-to-webhook bridge |
| PagerDuty | Events API v2 | Sends to incidents/events endpoint |
| Custom HTTP | Any endpoint | Receives JSON payload |
Every alert sends this JSON structure:
{
"event": "url_down",
"url": {
"name": "API_SERVER",
"url": "https://api.example.com"
},
"status": {
"code": 503,
"success": false,
"response_time_ms": 5000,
"error": "Service Unavailable",
"timestamp": "2026-01-21T10:30:00Z"
},
"previous_status": "up"
}alerts:
webhooks:
- url: "https://example.com/webhook"
# Whether this webhook is active (default: true)
enabled: true
# Send alert when URL transitions from UP → DOWN (default: true)
on_failure: true
# Send alert when URL transitions from DOWN → UP (default: true)
on_recovery: true
# Minimum seconds between alerts for the same URL (default: 300)
# Prevents alert spam if a service is flaky
cooldown_seconds: 300Verify webhook configuration before deployment:
webstatuspi test-alertOutput:
Testing 2 webhook(s)...
✓ SUCCESS: https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
✗ FAILED: https://example.com/broken-webhook
Result: 1/2 webhooks successful
For sensitive webhooks, use these patterns:
Option 1: Authentication Headers Configure your webhook endpoint to require an auth token, then test with curl:
curl -X POST https://example.com/webhook \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"event":"test"}'Option 2: HMAC Signature (Future) WebStatusPi may support HMAC-SHA256 signatures in future versions.
- Create Slack Incoming Webhook: https://api.slack.com/apps → Your App → Incoming Webhooks
- Copy webhook URL
- Add to
config.yaml:
alerts:
webhooks:
- url: "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX"
enabled: true
on_failure: true
on_recovery: true
cooldown_seconds: 300- Test:
webstatuspi test-alert - Your Slack channel will receive alerts when services go down
- Enable Developer Mode in Discord (User Settings → Advanced)
- Right-click channel → Edit Channel → Webhooks → Create Webhook
- Copy webhook URL
- Add to
config.yaml:
alerts:
webhooks:
- url: "https://discord.com/api/webhooks/123456789/abcdefg"
enabled: true
on_failure: true
on_recovery: false # Only alert on failures
cooldown_seconds: 600Install as a systemd service:
# Preview what will be installed
webstatuspi install-service --dry-run
# Install and start
sudo webstatuspi install-service --enable --start📋 Service management commands
sudo systemctl status webstatuspi # Check status
sudo journalctl -u webstatuspi -f # View live logs
sudo systemctl restart webstatuspi # Restart
sudo systemctl stop webstatuspi # Stopmonitor:
interval: 60 # seconds between checks
urls:
- name: "PROD_API" # max 10 characters
url: "https://api.example.com"
timeout: 10
- name: "STAGING"
url: "https://staging.example.com"
timeout: 5
server:
port: 8080
host: 0.0.0.0 # listen on all interfaces
database:
path: "./data/monitoring.db"
retention_days: 7 # auto-cleanup old dataFor Raspberry Pi 1B+:
| Setting | Recommendation |
|---|---|
| URLs | 5-10 max |
| Interval | 30+ seconds |
| Timeout | 10s or less |
# Setup
python3 -m venv venv
source venv/bin/activate
pip install .[dev]
# Run tests
pytest tests/ -v
# Run benchmark (Docker required)
cd benchmark && ./benchmark.shwebstatuspi/
├── webstatuspi/ # Core package
│ ├── __init__.py # CLI entry point
│ ├── alerter.py # Webhook alerts
│ ├── api.py # HTTP server
│ ├── config.py # Configuration
│ ├── database.py # SQLite operations
│ ├── models.py # Data models
│ └── monitor.py # URL checker
├── tests/ # Test suite
└── docs/ # Documentation
- 0.96" OLED display support
- Physical button navigation
- Buzzer alerts on failures
- Status LEDs (green/red)
API not accessible from other devices
- Check firewall:
sudo ufw allow 8080 - Verify config has
host: 0.0.0.0 - Check Pi IP:
ip addr show
High CPU usage
- Increase polling interval to 60+ seconds
- Reduce number of monitored URLs
- Check for slow/timing out URLs
Connection timeouts
- Increase
timeoutvalue in config - Test network:
ping google.com - Test URL manually:
curl -I <url>
See Troubleshooting Guide for more.
| Document | Description |
|---|---|
| Architecture | System design & database schema |
| Hardware | GPIO pins & OLED setup |
| Contributing | How to contribute |
| Development Rules | Code style & conventions |
MIT License — see LICENSE for details.
Built with ❤️ for Raspberry Pi enthusiasts
Lightweight. Reliable. Open Source.

