panvex

module
v0.0.0-...-592c247 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 29, 2026 License: MIT

README ΒΆ


Panvex

Fleet management control plane for Telemt MTProto proxy nodes

Quick Install Β β€’Β  Features Β β€’Β  Architecture Β β€’Β  Development Β β€’Β  Docker

Go React gRPC Linux


✨ Features

Feature Description
πŸ“Š Fleet Dashboard Real-time monitoring with metrics, health indicators, and alerts
πŸ‘₯ Managed Clients Centralized client management with secret rotation and quotas
πŸ€– Agent System Lightweight per-node agents with mTLS enrollment and gRPC streaming
πŸ—„οΈ Dual Storage SQLite for dev/lightweight, PostgreSQL for production
πŸ”„ Self-Update Panel and agents update themselves from GitHub Releases
πŸ“¦ Embedded UI Single binary ships the React dashboard β€” no separate web server
πŸ” TOTP 2FA Optional two-factor authentication for operator accounts
πŸ›‘οΈ RBAC Viewer, Operator, and Admin roles with middleware enforcement

πŸš€ Quick Install

Control Plane

sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/lost-coder/panvex/main/deploy/install.sh)"

Interactive wizard: ports, storage, TLS, firewall, admin account β€” all configured step by step.

Agent

sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/lost-coder/panvex/main/deploy/install-agent.sh)"

Requires a panel URL and enrollment token (create one in Settings β†’ Enrollment Tokens).

πŸ“‹ Non-interactive mode (CI / automation)
# Control Plane
PANVEX_ADMIN_PASS='<password>' \
PANVEX_HTTP_PORT=8080 \
PANVEX_GRPC_PORT=8443 \
  sudo -E bash install.sh

# Agent
PANVEX_PANEL_URL='https://panel.example.com' \
PANVEX_ENROLLMENT_TOKEN='<token>' \
  sudo -E bash install-agent.sh

Run bash install.sh --help for all environment variables.


πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    🌐 Browser                        β”‚
β”‚           React Β· TanStack Router/Query              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚              πŸ“‘ Control Plane (:8080)                β”‚
β”‚        HTTP API Β· WebSocket Β· Embedded UI            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚              πŸ”’ gRPC Gateway (:8443)                 β”‚
β”‚         mTLS Β· Bidirectional Stream Β· Jobs           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚              πŸ€– Agent (per Telemt node)              β”‚
β”‚       Heartbeats Β· Snapshots Β· Job Execution         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
πŸ“ Repository Layout
Directory Description
cmd/control-plane Control plane server (HTTP + gRPC + embedded UI)
cmd/agent Agent binary with bootstrap and enrollment
internal/controlplane Auth, jobs, presence, storage, server logic
internal/agent Telemt client, runtime, self-updater
internal/gatewayrpc Generated gRPC stubs (protobuf)
internal/security Enrollment, crypto, mTLS CA
web React dashboard (Vite + TailwindCSS 4 + TanStack)
db/migrations PostgreSQL and SQLite schema migrations
proto Protobuf gateway contract
deploy Install scripts, Docker Compose, nginx config
πŸ”§ Tech Stack
Layer Technology
Backend Go 1.26, chi/v5, pgx/v5, modernc.org/sqlite, gRPC
Frontend React 19, Vite 8, TailwindCSS 4, TanStack Router + Query
UI Kit Inlined under web/src/ui/ β€” Radix UI primitives + CVA
Database PostgreSQL (primary) Β· SQLite (lightweight)
Deploy Multi-stage Docker Β· systemd Β· nginx

πŸ’» Development

Prerequisites

  • Go 1.26+ Β Β·Β  Node.js 22+ Β Β·Β  sqlc Β Β·Β  protoc + Go plugins

Backend

go build ./...                    # Build all
go test ./...                     # Run tests
go test -race ./...               # Race detector
golangci-lint run ./...           # Lint
sqlc generate                     # Regenerate DB code

Frontend

cd web
npm install                       # Install deps
npm run dev                       # Dev server (proxies API to :8080)
npm run build                     # Production build
npm run lint                      # ESLint

πŸƒ Local Development Flow

1. Bootstrap admin:

go run ./cmd/control-plane bootstrap-admin \
  -username admin \
  -password '<strong-password>'

2. Start control plane:

go run ./cmd/control-plane -http-addr :8080 -grpc-addr :8443

3. Start frontend dev server:

cd web && npm run dev

Dashboard at http://localhost:5173, API proxied to :8080

πŸ“¦ Single binary build
cd web && npm run build:embed
cd .. && go build -tags embeddedui -o panvex-control-plane ./cmd/control-plane

🐳 Docker

Each compose file ships a bootstrap service under --profile bootstrap that creates the first admin one-shot. It refuses to plant an account on a non-empty store, so it's safe to re-run.

SQLite (lightweight)
# 1. First-run admin (run before bringing up the backend so the SQLite
#    file isn't contended).
PANVEX_BOOTSTRAP_PASSWORD='<strong-password>' \
  docker compose -f deploy/docker-compose.sqlite.yml \
    --profile bootstrap run --rm bootstrap

# 2. Start the stack.
docker compose -f deploy/docker-compose.sqlite.yml up --build -d
PostgreSQL (dev β€” default password, plaintext DB traffic)
# 1. Start Postgres + backend (creates schema on first boot).
docker compose -f deploy/docker-compose.postgres.yml up --build -d

# 2. First-run admin.
PANVEX_BOOTSTRAP_PASSWORD='<strong-password>' \
POSTGRES_PASSWORD='<db-password>' \
  docker compose -f deploy/docker-compose.postgres.yml \
    --profile bootstrap run --rm bootstrap
PostgreSQL (production β€” TLS, no default credentials)
# 1. Bring up the stack. Required env vars are enforced via ${VAR:?...}.
POSTGRES_PASSWORD='<strong-db-password>' \
PANVEX_ENCRYPTION_KEY='<strong-encryption-key>' \
  docker compose -f deploy/docker-compose.prod.yml up --build -d

# 2. First-run admin. Reuse the same PANVEX_ENCRYPTION_KEY so freshly
#    minted secrets are readable to the running backend.
POSTGRES_PASSWORD='<strong-db-password>' \
PANVEX_ENCRYPTION_KEY='<strong-encryption-key>' \
PANVEX_BOOTSTRAP_PASSWORD='<strong-admin-password>' \
  docker compose -f deploy/docker-compose.prod.yml \
    --profile bootstrap run --rm bootstrap

The prod profile refuses to start without POSTGRES_PASSWORD and PANVEX_ENCRYPTION_KEY, forces sslmode=require, sets resource limits, JSON-log rotation (15 MiB Γ— 10), PANVEX_ENV=production, and binds publishers to loopback (terminate TLS at a reverse proxy β€” see deploy/nginx/default.conf).

Override the admin username via PANVEX_BOOTSTRAP_USERNAME (default: admin).

Dashboard: http://localhost:8080 Β Β·Β  gRPC: localhost:8443


πŸ€– Agent Deployment

  1. Create an enrollment token: Settings β†’ Enrollment Tokens
  2. On each Telemt server:
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/lost-coder/panvex/main/deploy/install-agent.sh)"
Manual bootstrap (without installer)
./panvex-agent bootstrap \
  -panel-url https://panel.example.com \
  -enrollment-token '<token>' \
  -state-file /var/lib/panvex-agent/agent-state.json

πŸ‘₯ Managed Clients

Create and manage Telemt clients centrally from the dashboard:

  • πŸ”‘ Generate secrets and user_ad_tag
  • πŸ“ Set limits: connections, unique IPs, quota, expiration
  • 🌐 Assign by fleet group or individual nodes
  • πŸ”„ Rotate secrets without recreating the client
  • πŸ“ˆ Live deployment status, connection links, and usage per node

πŸ” Security

Two-Factor Authentication β€” TOTP 2FA is optional. Enable in Profile page.

Emergency TOTP reset via CLI:

./panvex-control-plane reset-user-totp \
  -storage-driver sqlite \
  -storage-dsn /var/lib/panvex/panvex.db \
  -username admin

πŸ”„ Updates

The control plane checks GitHub Releases for new versions automatically.

Method Command
Dashboard Settings β†’ Updates β†’ Update Panel / Update Agent
CLI ./panvex-control-plane self-update
Auto-update Enable in Settings β†’ Updates (disabled by default)

Agents can be updated individually or in bulk. The panel sends an update job via gRPC β€” the agent downloads and installs the new binary automatically.


Built with ❀️ for Telemt fleet operators

Directories ΒΆ

Path Synopsis
cmd
agent command
control-plane command
db
migrations/postgres
Package pgmigrations exposes the PostgreSQL goose migrations as an embed.FS so the storage/postgres package (and any tooling that wants to run the same migrations out-of-band) can call goose.SetBaseFS without duplicating the .sql files.
Package pgmigrations exposes the PostgreSQL goose migrations as an embed.FS so the storage/postgres package (and any tooling that wants to run the same migrations out-of-band) can call goose.SetBaseFS without duplicating the .sql files.
migrations/sqlite
Package sqlitemigrations exposes the SQLite goose migrations as an embed.FS so the storage/sqlite package (and any tooling that wants to run the same migrations out-of-band) can call goose.SetBaseFS without duplicating the .sql files.
Package sqlitemigrations exposes the SQLite goose migrations as an embed.FS so the storage/sqlite package (and any tooling that wants to run the same migrations out-of-band) can call goose.SetBaseFS without duplicating the .sql files.
internal
controlplane/agentrevocation
Package agentrevocation owns the wire-level contract used by the control-plane to tell a deregistered agent that it should stop reconnecting.
Package agentrevocation owns the wire-level contract used by the control-plane to tell a deregistered agent that it should stop reconnecting.
controlplane/agents
Package agents holds the control-plane's agent-lifecycle domain model.
Package agents holds the control-plane's agent-lifecycle domain model.
controlplane/clients
Package clients holds the control-plane's managed-client domain model.
Package clients holds the control-plane's managed-client domain model.
controlplane/eventbus
Package eventbus provides an in-process audit/event pub/sub facade with a pluggable Backend interface.
Package eventbus provides an in-process audit/event pub/sub facade with a pluggable Backend interface.
controlplane/fleet
Package fleet owns the create/update/delete lifecycle for fleet groups and the integrations scaffolded on top of them.
Package fleet owns the create/update/delete lifecycle for fleet groups and the integrations scaffolded on top of them.
controlplane/fleet/integrations
Package integrations wires fleet-group integrations (e.g.
Package integrations wires fleet-group integrations (e.g.
controlplane/otel
Package otel sets up OpenTelemetry distributed tracing for the Panvex control-plane.
Package otel sets up OpenTelemetry distributed tracing for the Panvex control-plane.
controlplane/secretvault
Package secretvault provides at-rest envelope encryption for sensitive fields (client secrets, TOTP secrets, etc.).
Package secretvault provides at-rest envelope encryption for sensitive fields (client secrets, TOTP secrets, etc.).
controlplane/sessions
Package sessions holds the control-plane's HTTP session/auth support primitives that are orthogonal to the core auth service (controlplane/auth).
Package sessions holds the control-plane's HTTP session/auth support primitives that are orthogonal to the core auth service (controlplane/auth).
controlplane/storage/migrateguard
Package migrateguard refuses to apply migrations that would silently destroy production data unless the operator has explicitly opted in.
Package migrateguard refuses to apply migrations that would silently destroy production data unless the operator has explicitly opted in.
controlplane/storage/postgres
Package postgres bulk insert helpers (P3-PERF-01a).
Package postgres bulk insert helpers (P3-PERF-01a).
controlplane/storage/sqlite
Package sqlite bulk insert helpers (P3-PERF-01a).
Package sqlite bulk insert helpers (P3-PERF-01a).
controlplane/updates
Package updates holds the control-plane's self-update subsystem: release discovery, artifact download, signature/checksum verification, and atomic binary replacement.
Package updates holds the control-plane's self-update subsystem: release discovery, artifact download, signature/checksum verification, and atomic binary replacement.
security
Package security provides primitives for verifying release-artifact signatures.
Package security provides primitives for verifying release-artifact signatures.
scripts
migration-test command
Command seed populates a fresh SQLite database with synthetic, production-scale data for the goose migration stress test (P2-TEST-03).
Command seed populates a fresh SQLite database with synthetic, production-scale data for the goose migration stress test (P2-TEST-03).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL