Self-hosted uptime monitor. It periodically pings your URLs/services, stores and displays uptime history, and sends notifications (Telegram, email) when a service goes down or recovers. Designed to deploy with a single command.
Stack: React 19 + TypeScript (Vite) · FastAPI (Python) · Docker.
- Monitor HTTP(S) endpoints on a per-monitor interval (GET / HEAD / POST)
- Live dashboard with status, uptime %, response time, and check history
- Down/recovery notifications via Telegram and email (planned)
- Single-command self-hosted deploy via Docker Compose (planned)
Single-command deploy is the goal. Once the Docker files land:
cp .env.example .env # fill in secrets (Telegram, SMTP, …)
docker compose up --build # frontend + backend + reverse-proxy- UI → http://localhost
- API → http://localhost/api
- API docs (FastAPI) → http://localhost/api/docs
npm install
npm run dev # Vite dev server with HMR → http://localhost:5173
npm run build # tsc -b typecheck, then vite build → dist/
npm run lint # eslint
npm run preview # serve the production build locallyThe dev server proxies /api to the backend on :8000 (see vite.config.ts); override the
target with VITE_PROXY_TARGET.
cd backend
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000 # entry path TBD during implementationSecrets go in .env (never commit it). Key variables:
| Variable | Purpose |
|---|---|
VITE_API_BASE |
API base path for the frontend (default /api) |
VITE_PROXY_TARGET |
Dev proxy target for /api (default http://localhost:8000) |
DATABASE_URL |
Backend DB connection (SQLite by default) |
TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID |
Telegram notifications (optional) |
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASSWORD / NOTIFY_EMAIL_TO |
Email notifications (optional) |
Full table and details in OPERATIONS.md.
The frontend (src/api.ts, src/types.ts) defines the contract the backend must implement:
| Method & path | Purpose |
|---|---|
GET /api/monitors |
list monitors |
POST /api/monitors |
create a monitor (MonitorInput) |
PATCH /api/monitors/{id} |
partial update |
DELETE /api/monitors/{id} |
delete a monitor |
GET /api/monitors/{id}/checks?limit=N |
check history |
A Monitor includes backend-derived fields: status (up/down/unknown),
uptime_percentage, last_checked_at, last_response_time_ms.
- Frontend — Vite SPA (React 19); talks to the API at
/api, behind a reverse proxy in prod. - Backend — FastAPI + SQLAlchemy; stores monitors and check history.
- Scheduler — APScheduler in the backend polls targets on their interval, independent of HTTP request handling, and records each check.
- Notifications — pluggable channels (Telegram, email) triggered on status change, configured via environment variables.
- Storage — SQLite by default, persisted via a Docker volume.
├── src/ # React frontend
│ ├── App.tsx # Dashboard: loads/polls monitors, summary & states
│ ├── App.css # Dashboard styles
│ ├── api.ts # Typed fetch layer against /api
│ ├── auth.ts # Admin auth system
│ ├── types.ts # API contract (Monitor, MonitorInput, Check)
│ ├── main.tsx # SPA entry point
│ ├── index.css # Global styles
│ └── components/ # MonitorCard, MonitorForm, StatusBadge, UptimeBar, AdminBar
├── backend/ # FastAPI backend
│ ├── app/ # Application package
│ │ ├── main.py # FastAPI entry point
│ │ ├── config.py # Settings (pydantic-settings)
│ │ ├── database.py # SQLAlchemy engine & session
│ │ ├── models.py # ORM models
│ │ ├── schemas.py # Pydantic schemas
│ │ ├── routers.py # API endpoints
│ │ ├── services.py # Monitor check logic
│ │ ├── scheduler.py # APScheduler background polling
│ │ └── notifications.py # Telegram / email channels
│ ├── requirements.txt # Python dependencies
│ ├── Dockerfile # Backend image
│ └── .dockerignore
├── public/ # Static assets (Analytics.png)
├── index.html # Vite HTML entry
├── vite.config.ts # Vite config incl. /api dev proxy
├── eslint.config.js # ESLint flat config
├── tsconfig.json # Root TS project references
├── tsconfig.app.json # TS config for src/
├── tsconfig.node.json # TS config for config files
├── package.json # Frontend deps & scripts
├── package-lock.json
├── Dockerfile # Frontend image (nginx-served build)
├── nginx.conf # Reverse proxy: UI + /api
├── docker-compose.yml # Single-command deploy (frontend + backend)
├── .dockerignore
├── .env.example # Sample environment variables
├── .gitignore
└── README.md