Real-time dashboard for monitoring Syncthing relay nodes
  • Go 50.3%
  • TypeScript 46.1%
  • Dockerfile 1.1%
  • JavaScript 1.1%
  • Makefile 0.8%
  • Other 0.6%
Find a file
nghialele 6a7396e4e0 feat: add persistent lifetime bytes proxied tracking across relay restarts
Track cumulative bytes proxied that persists across relay process restarts
by detecting start time changes and snapshotting previous bytesProxied into
an accumulated total stored in a new relay_lifetime SQLite table.

- Add StartTime field to RelayRawStatus model
- Add LifetimeBytesProxied to RelayStatus (backend + frontend)
- Create relay_lifetime table with accumulated_bytes, last_start_time, last_bytes_proxied
- Detect restarts in collector when startTime changes
- Add "Lifetime Proxied" summary card and sortable "Lifetime" column in relay table

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-06-15 18:50:05 +07:00
cmd/server feat: remove throughput card, add beta.syncthi.ng link, fix make dev 2026-06-15 10:17:58 +07:00
frontend feat: add persistent lifetime bytes proxied tracking across relay restarts 2026-06-15 18:50:05 +07:00
internal feat: add persistent lifetime bytes proxied tracking across relay restarts 2026-06-15 18:50:05 +07:00
.dockerignore feat: add Docker support for deployment 2026-06-15 10:22:00 +07:00
.gitignore docs: add Docker deployment instructions to README 2026-06-15 10:38:29 +07:00
config.example.yaml feat: simplify config to use status_url instead of relay:// format 2026-06-15 09:41:58 +07:00
docker-compose.yml feat: add Docker support for deployment 2026-06-15 10:22:00 +07:00
Dockerfile feat: add Docker support for deployment 2026-06-15 10:22:00 +07:00
embed.go v1: initial relay stats dashboard with relay:// URL format 2026-06-15 09:40:34 +07:00
go.mod v1: initial relay stats dashboard with relay:// URL format 2026-06-15 09:40:34 +07:00
go.sum v1: initial relay stats dashboard with relay:// URL format 2026-06-15 09:40:34 +07:00
Makefile feat: remove throughput card, add beta.syncthi.ng link, fix make dev 2026-06-15 10:17:58 +07:00
README.md docs: add Docker deployment instructions to README 2026-06-15 10:38:29 +07:00

Syncthing Relay Stats Dashboard

A real-time dashboard for monitoring your Syncthing relay nodes. Displays live stats including active sessions, connections, data proxied, throughput, and relay locations on a world map.

Architecture

  • Backend: Go (single binary, embeds the React frontend)
  • Frontend: React + TypeScript + Tailwind CSS + Recharts + react-simple-maps
  • Real-time: WebSocket for live updates
  • Storage: SQLite for persistent history
  • GeoIP: MaxMind GeoLite2 (with free API fallback)

Quick Start

1. Configure your relays

cp config.example.yaml config.yaml
# Edit config.yaml with your relay URLs

Your relay status endpoints should be accessible at http://<relay-ip>:22070/status.

2. Build & Run

make build
make run

Or for development with hot-reload:

make dev

3. Open Dashboard

Navigate to http://localhost:8080

Docker Deployment

# 1. Configure your relays
cp config.example.yaml config.yaml
# Edit config.yaml with your relay URLs

# 2. Build and start
docker compose up -d

# 3. View logs
docker compose logs -f

The dashboard will be available at http://localhost:8080.

Using Docker directly

# Build the image
docker build -t syncthing-relay-stats .

# Run with config mounted
docker run -d \
  --name syncthing-relay-stats \
  -p 8080:8080 \
  -v $(pwd)/config.yaml:/app/config.yaml:ro \
  syncthing-relay-stats

Container Details

  • Base: Alpine Linux (minimal footprint)
  • Port: 8080
  • Config: Mount your config.yaml to /app/config.yaml
  • Data: Persisted in /app/data volume (SQLite database)
  • Health check: Built-in at /health endpoint

Configuration

See config.example.yaml for all options:

Option Default Description
server.listen :8080 HTTP listen address
server.dev_mode false Proxy to Vite dev server
relays[].status_url Status endpoint URL (http://ip:22070/status)
relays[].name Human-friendly label
polling.interval 5s How often to fetch stats
polling.timeout 3s HTTP timeout per relay
history.max_points 720 Max history points per relay
geoip.database_path ./GeoLite2-City.mmdb MaxMind database path
geoip.fallback_api true Use ip-api.com if DB missing
database.path ./relay-stats.db SQLite database path

GeoIP Setup

For the world map, download the free MaxMind GeoLite2-City database:

  1. Create a free account at maxmind.com
  2. Download GeoLite2-City.mmdb
  3. Place it in the project root

If the database isn't available, the app falls back to ip-api.com (rate-limited to 45 req/min).

API Endpoints

Method Path Description
GET /api/relays Current status of all relays
GET /api/relays/{id}/history Time-series history for a relay
GET /ws WebSocket for real-time updates
GET /health Health check

Project Structure

├── cmd/server/main.go       # Entry point
├── internal/
│   ├── api/                  # HTTP router & WebSocket handler
│   ├── collector/            # Background relay polling
│   ├── config/               # YAML config loading
│   ├── geoip/                # MaxMind + fallback IP lookup
│   ├── hub/                  # WebSocket broadcast hub
│   ├── models/               # Shared data types
│   └── storage/              # SQLite persistence
├── frontend/                 # React app (Vite + TypeScript)
│   └── src/
│       ├── components/       # UI components
│       ├── hooks/            # WebSocket + Zustand store
│       ├── types/            # TypeScript interfaces
│       └── utils/            # Formatting helpers
├── embed.go                  # go:embed for frontend assets
├── config.example.yaml       # Example configuration
└── Makefile                  # Build commands