README.md
Rama main · réplica de lectura del repositorio original.
[](https://github.com/gregyjames/NanoStatus/actions/workflows/docker-image.yml)



# NanoStatus
Finally got a cursor subscription so wanted to build something cool. NanoStatus is a lightweight, single-container monitoring dashboard built with Go and React. Monitor your services' uptime, response times, and health in real-time with a beautiful, modern interface. I personally made this for my PiZero, UptimeKuma was a little too heavy so wanted to make something a little lighter.
# Sample

## ✨ Features
- 🚀 **Single Binary Deployment** - Everything embedded in one Go binary
- 📊 **Real-time Monitoring** - Server-Sent Events (SSE) for instant updates
- 🎨 **Modern UI** - Sleek dark theme with glassmorphism effects and smooth animations
- 📈 **Response Time Charts** - Historical data with multiple time frames (1h, 12h, 1w, 1y)
- 🔍 **Service Management** - Add, edit, pause, and delete monitors
- 📱 **Fully Responsive** - Works beautifully on desktop, tablet, and mobile
- 💾 **SQLite Database** - Lightweight persistence with automatic cleanup
- ⚡ **Efficient Updates** - Only sends data when values actually change
- 🎯 **Customizable Intervals** - Set individual check intervals per service
- 🧹 **Auto Cleanup** - Automatically removes check history older than 1 year
## 🚀 Quick Start
### Using Docker (Recommended)
1. **Build the Docker image:**
```bash
docker build -t nanostatus .
```
2. **Run the container:**
```bash
docker run -p 8080:8080 -v "$(pwd)/data:/data" nanostatus
```
The application will be available at `http://localhost:8080`
**Note:** The `-v "$(pwd)/data:/data"` flag persists the database across container restarts.
3. **Access the dashboard:**
Open `http://localhost:8080` in your browser
### Local Development
#### Prerequisites
- [Bun](https://bun.sh) (for frontend)
- [Go](https://go.dev) 1.24+ (for backend)
#### Running Locally
1. **Build the frontend:**
```bash
cd src
bun install
bun run build.ts --outdir=../dist
cd ..
```
2. **Run the Go server:**
```bash
go run .
```
Or build and run:
```bash
go build -o nanostatus .
./nanostatus
```
3. **Access the application:**
Open http://localhost:8080 in your browser
#### Using Makefile
```bash
make build # Build both frontend and backend
make run # Build and run the application
make dev-frontend # Run frontend dev server (with hot reload)
make dev-backend # Run Go server (requires built frontend)
make clean # Clean build artifacts
```
## 📖 How It Works
### Architecture
- **Backend**: Go HTTP server with embedded frontend static files
- **Frontend**: React with TypeScript, Tailwind CSS, and Framer Motion
- **Database**: SQLite with GORM ORM
- **Real-time Updates**: Server-Sent Events (SSE) for efficient streaming
- **Background Jobs**:
- Automatic service health checks based on individual intervals
- Daily cleanup of check history older than 1 year (runs at midnight)
### Monitoring
- Services are checked via actual HTTP requests
- Response times are measured and stored in the database
- Uptime is calculated from the last 24 hours of check history
- Stats are only calculated and broadcast when values change
- Updates are streamed to clients via SSE (no polling needed)
### Data Management
- Check history is stored in SQLite for historical analysis
- Automatic cleanup runs daily at 12:00 AM to remove data older than 1 year
- Database uses WAL mode for better concurrency
- All data persists in `/data` volume when using Docker
## 🔌 API Endpoints
### REST API
- `GET /api/monitors` - List all monitors
- `POST /api/monitors/create` - Create a new monitor
- `GET /api/stats` - Get overall statistics (only unpaused services)
- `GET /api/response-time?id=<id>&range=<range>` - Get response time history
- `range` options: `1h`, `12h`, `24h`, `1w`, `1y` (default: `24h`)
- `GET /api/monitor?id=<id>` - Get specific monitor details
- `PUT /api/monitor?id=<id>` - Update a monitor or toggle pause state
- `DELETE /api/monitor?id=<id>` - Delete a monitor
### Server-Sent Events (SSE)
- `GET /api/events` - Real-time event stream
- Event types: `monitor_update`, `monitor_added`, `monitor_deleted`, `stats_update`
- Automatically reconnects on connection loss
- Keepalive messages every 30 seconds
## ⚙️ Configuration
### Environment Variables
- `PORT` - Server port (default: `8080`)
- `DB_PATH` - Database file path
- Default: `./nanostatus.db` (local) or `/data/nanostatus.db` (Docker)
### YAML Configuration
You can pre-populate monitors using a YAML configuration file. Place `monitors.yaml` in the same directory as your database file.
**Example `monitors.yaml` (in the same directory as your database):**
```yaml
monitors:
- name: "Example.com"
url: "https://example.com"
icon: "🌐"
checkInterval: 60
isThirdParty: false
paused: false
- name: "Google"
url: "https://google.com"
icon: "🔍"
checkInterval: 30
isThirdParty: true
paused: false
- name: "GitHub"
url: "https://github.com"
icon: "💻"
checkInterval: 120
isThirdParty: true
paused: false
```
**Configuration Fields:**
- `name` (required) - Display name for the service
- `url` (required) - Full URL to monitor (e.g., `https://example.com`)
- `icon` (optional) - Emoji icon to display
- `checkInterval` (optional) - How often to check in seconds (default: 60)
- `isThirdParty` (optional) - Whether this is a third-party service (default: false)
- `paused` (optional) - Whether monitoring should start paused (default: false)
**Location:**
- The YAML file must be named `monitors.yaml` and placed in the same directory as your database
- For Docker: If `DB_PATH=/data/nanostatus.db`, place the file at `/data/monitors.yaml`
- For local: If database is at `./nanostatus.db`, place the file at `./monitors.yaml`
**How It Works:**
- The YAML configuration is synchronized on every server startup
- Each monitor from YAML gets a hash calculated from its configuration
- The system compares hashes to detect changes:
- **New monitors** in YAML are created
- **Changed monitors** (different hash) are updated (preserving runtime data like status and uptime)
- **Removed monitors** (no longer in YAML) are deleted
- **Unchanged monitors** are left as-is
- Monitors created via the UI/API are **not** managed by YAML and won't be modified
- If a monitor with the same name/URL exists but was created via UI/API, the YAML version will be skipped to avoid duplicates
### Service Configuration
When creating a monitor via the UI or API, you can configure:
- **Name**: Display name for the service
- **URL**: Full URL to monitor (e.g., `https://example.com`)
- **Icon**: Optional emoji icon
- **Check Interval**: How often to check (10-3600 seconds, default: 60)
- **Third-party Service**: Flag for external services
## 🎯 Features in Detail
### Service Management
- **Add Services**: Create new monitors with custom check intervals
- **Edit Services**: Update name, URL, icon, and check interval
- **Pause/Resume**: Temporarily disable monitoring for specific services
- **Delete Services**: Remove monitors and their history
### Real-time Updates
- **SSE Streaming**: All updates pushed instantly to connected clients
- **Change Detection**: Stats only calculated and sent when values change
- **Debouncing**: Rapid monitor updates are batched for efficiency
- **No Polling**: Frontend receives updates via SSE, eliminating HTTP polling
### Response Time History
- **Multiple Time Frames**: View data for 1 hour, 12 hours, 1 week, or 1 year
- **Interactive Charts**: Beautiful area charts with gradient fills
- **Time-based Formatting**: Labels adapt to the selected time range
### Statistics
- **Overall Uptime**: Average uptime across all unpaused services
- **Service Counts**: Number of services online/offline (unpaused only)
- **Average Response Time**: Calculated from last 24 hours of check history
- **Real-time Updates**: Stats update automatically when monitors change
## 🏗️ Project Structure
```
.
├── main.go # Main server entry point and routing
├── models.go # Data models and structures
├── database.go # Database initialization and seeding
├── config.go # YAML configuration loader
├── checker.go # Service health checking logic
├── stats.go # Statistics calculation
├── sse.go # Server-Sent Events broadcasting
├── handlers.go # HTTP API endpoint handlers
├── cleanup.go # Background cleanup jobs
├── go.mod # Go dependencies
├── go.sum # Go dependency checksums
├── Dockerfile # Standard multi-stage Docker build (distroless)
├── Dockerfile.minimal # Minimal Docker build with UPX compression (scratch)
├── Makefile # Build automation
├── monitors.yaml.example # Example YAML configuration file
├── dist/ # Frontend build output (generated)
├── nanostatus.db # SQLite database (generated)
├── monitors.yaml # YAML config (optional, same dir as DB)
├── src/ # Frontend source code
│ ├── src/
│ │ ├── App.tsx # Main React component
│ │ ├── components/ # React components
│ │ │ ├── Header.tsx
│ │ │ ├── StatsGrid.tsx
│ │ │ ├── ServicesGrid.tsx
│ │ │ ├── ServiceCard.tsx
│ │ │ ├── MonitorDetails.tsx
│ │ │ ├── AddServiceDialog.tsx
│ │ │ ├── EditServiceDialog.tsx
│ │ │ └── ui/ # shadcn/ui components
│ │ ├── types/ # TypeScript type definitions
│ │ └── ...
│ └── package.json
└── README.md
```
## 🔧 Development
### Building
```bash
# Build frontend
cd src
bun install
bun run build.ts --outdir=../dist
# Build backend
go build -o nanostatus .
```
### Docker Build
The Dockerfile uses a multi-stage build:
1. **Frontend Builder**: Builds React app with Bun
2. **Backend Builder**: Compiles Go binary with embedded frontend
3. **Final Stage**: Minimal distroless image (no shell, no package manager)
Result: Ultra-small, secure container (~16MB)
## 📝 License
See LICENSE file for details.
## 🙏 Acknowledgments
Built with:
- [Go](https://go.dev) - Backend server
- [React](https://react.dev) - Frontend framework
- [Bun](https://bun.sh) - JavaScript runtime and package manager
- [Tailwind CSS](https://tailwindcss.com) - Styling
- [Framer Motion](https://www.framer.com/motion/) - Animations
- [Recharts](https://recharts.org) - Charting
- [shadcn/ui](https://ui.shadcn.com) - UI components
- [GORM](https://gorm.io) - ORM
- [SQLite](https://sqlite.org) - Database
### Icon Attribution
The favicon/logo is from the [small-n-flat](http://paomedia.github.io/small-n-flat/) icon set, licensed under [CC0 1.0 Universal](http://creativecommons.org/publicdomain/zero/1.0/). See [ICON_LICENSE](ICON_LICENSE) for full license text.