- go.mod/go.sum : require + replace pour viewLogs et viewServices (chemins locaux) - main.go : enregistrement loader.RegisterModule(viewlogs.New()) + viewservices.New() - Dockerfile : build context parent proxmoxPanel/ pour accéder aux 3 repos - docker-compose.yml : context: .. + dockerfile: core/backend/Dockerfile - nginx.conf : locations /viewLogs/ et /viewServices/ proxyfiées vers backend:3001 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| backend | ||
| frontend | ||
| .gitattributes | ||
| .gitignore | ||
| docker-compose.yml | ||
| LICENSE | ||
| README.md | ||
| SUIVI.md | ||
ProxmoxPanel — CORE
A self-hosted web management panel for Proxmox VE infrastructure. Manage LXC containers and VMs, run package updates, open interactive terminals, browse files — all from a single web interface with a dark/light Neumorphism UI.
Features
- Dashboard — Configurable widget grid with drag-and-drop (LXC/VM status, shortcuts, metrics)
- Proxmox — Real-time LXC/VM list with start/stop actions, live status via WebSocket
- Updates — Run
apt upgradeon the host or any LXC, with streamed output - Terminal — Interactive SSH terminal in the browser (xterm.js + PTY)
- Settings — Per-user preferences (theme, language, sidebar position), instance config
- Modules — Enable/disable optional modules without restarting
Requirements
- Docker + Docker Compose
- Proxmox VE 7.x or 8.x
- SSH access to the Proxmox host (password authentication)
- A Proxmox API token (read-only
PVEAuditorrole is sufficient for metrics) - Reverse proxy recommended (Traefik, Nginx, Caddy) for HTTPS in production
Quick Start
git clone <repository-url>
cd core
docker compose up -d --build
Open http://localhost (or your server's IP) in a browser. The installation wizard appears on first launch and guides you through the configuration.
Installation Wizard
The wizard runs automatically on first launch and collects:
- Instance name and public URL (auto-detected from the HTTP request)
- SSH host — address and port of the Proxmox host (e.g.
192.168.1.10:22) - SSH credentials — Linux username and password used for PAM authentication
- Proxmox API — URL and API token (e.g.
https://192.168.1.10:8006) - Default language —
enorfr
All sensitive values (SSH password, API token) are encrypted with AES-256-GCM before storage.
Authentication
ProxmoxPanel uses PAM authentication via SSH: the panel attempts an SSH connection to the Proxmox host using the credentials provided at login. If the connection succeeds, the user is authenticated. Group membership is checked with id -nG — users in the sudo or wheel group are granted admin privileges.
No separate user database is required. Any Linux user with SSH access can log in.
Sessions use JWT RS256 (15-minute access tokens + 7-day refresh cookies).
Configuration
All configuration is stored in SQLite (/app/data/panel.db). There are no environment variables or config files to manage. Settings are accessible from the web interface under Settings → General (admin only).
| Setting | Description |
|---|---|
ssh_host |
SSH address of the Proxmox host (host:port) |
ssh_username |
SSH username |
ssh_password |
SSH password (AES-256-GCM encrypted) |
proxmox_url |
Proxmox API base URL (https://host:8006) |
proxmox_token |
Proxmox API token (AES-256-GCM encrypted) |
instance_name |
Display name shown in the UI |
public_url |
Public URL of the panel |
default_lang |
Default language (en or fr) |
Architecture
core/
├── docker-compose.yml # Two services: backend + frontend
├── backend/ # Go 1.23+ — REST API + WebSocket server
│ ├── main.go
│ ├── internal/
│ │ ├── api/ # HTTP handlers (chi router)
│ │ ├── auth/ # PAM-via-SSH + JWT RS256
│ │ ├── crypto/ # AES-256-GCM secret encryption
│ │ ├── db/ # SQLite + versioned migrations
│ │ ├── proxmox/ # Proxmox REST API client
│ │ ├── ssh/ # SSH connection pool
│ │ ├── websocket/ # WebSocket hub (pub/sub by channel)
│ │ └── audit/ # Audit log
│ └── modules/ # Module system (compiled-in, conditional init)
└── frontend/ # Vue 3 + Vite + TypeScript — Nginx static
└── src/
├── views/ # One view per module
├── stores/ # Pinia (auth, ui)
├── styles/ # Neumorphism CSS (dark + light themes)
└── locales/ # i18n — en.json, fr.json
Backend
- Language: Go 1.23+
- Router:
go-chi/chiv5 - WebSocket:
gorilla/websocket - Database:
modernc.org/sqlite(pure Go, no CGO) - JWT:
golang-jwt/jwtv5, RS256, keys auto-generated at first start - SSH:
golang.org/x/crypto/ssh
Frontend
- Framework: Vue 3 (Composition API)
- Build tool: Vite 6 — compiled to static HTML/CSS/JS, served by Nginx
- State: Pinia
- i18n: vue-i18n v11
- Terminal: xterm.js +
@xterm/addon-fit+@xterm/addon-attach - File editor: CodeMirror 6
- Design: Custom Neumorphism CSS, dark/light themes via
data-themeon<html>
Node.js is used only during the Docker build stage to compile the frontend. The runtime image is Nginx only.
Data persistence
A Docker volume (proxmoxpanel-data) stores:
panel.db— SQLite databasekeys/jwt.key,keys/jwt.pub— RSA-2048 key pair for JWT signingmaster.key— AES master secret for credential encryption
Do not delete this volume without backing up panel.db first.
WebSocket channels
| Endpoint | Description |
|---|---|
GET /ws/proxmox |
LXC/VM status updates (polled every 10s) |
GET /ws/updates/{jobId} |
Streaming apt output for an update job |
GET /ws/terminal |
Interactive SSH PTY terminal |
WebSocket authentication uses a ?token= query parameter (standard Authorization header is not supported by browser WebSocket API).
Module System
Modules are compiled into the binary but initialized only if enabled in the database. This allows disabling features without rebuilding.
Each module implements the Module interface:
type Module interface {
ID() string
Register(registry Registry) error
}
A module can register HTTP routes, WebSocket channels, dashboard widgets, settings tabs, translations, and database migrations via the Registry interface.
Core modules (always enabled): dashboard, proxmox, updates, settings
Optional modules (can be toggled): files, terminal, logs, services
See backend/modules/ for available modules and their documentation.
Reverse Proxy
ProxmoxPanel listens on port 80 (HTTP). In production, place it behind a reverse proxy for TLS termination.
Example Traefik dynamic configuration:
http:
routers:
proxmoxpanel:
rule: "Host(`panel.example.com`)"
entryPoints: [websecure]
service: proxmoxpanel
tls:
certResolver: letsencrypt
services:
proxmoxpanel:
loadBalancer:
servers:
- url: "http://<panel-host>:80"
healthCheck:
path: /api/health
interval: 30s
API
All API routes are prefixed with /api/.
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/health |
— | Health check |
| GET | /api/install/check |
— | Installation status |
| GET | /api/install/status |
— | Detected URL, pre-fill wizard |
| POST | /api/install/test-ssh |
— | Test SSH connectivity |
| POST | /api/install/configure |
— | Save initial configuration |
| POST | /api/auth/login |
— | Login (PAM via SSH) |
| POST | /api/auth/logout |
JWT | Logout |
| POST | /api/auth/refresh |
Cookie | Refresh access token |
| GET | /api/auth/me |
JWT | Current user profile |
| PATCH | /api/auth/preferences |
JWT | Update user preferences |
| GET | /api/proxmox/resources |
JWT | All Proxmox resources |
| GET | /api/proxmox/lxc |
JWT | LXC list |
| POST | /api/proxmox/lxc/{vmid}/start |
JWT+Admin | Start LXC |
| POST | /api/proxmox/lxc/{vmid}/stop |
JWT+Admin | Stop LXC |
| POST | /api/updates/run |
JWT+Admin | Start update job |
| GET | /api/updates/history |
JWT | Update history |
| GET | /api/settings |
JWT+Admin | All settings |
| PUT | /api/settings/{key} |
JWT+Admin | Update a setting |
| GET | /api/settings/audit |
JWT+Admin | Audit log |
| GET | /api/modules |
JWT | Module list |
| POST | /api/modules/{id}/enable |
JWT+Admin | Enable a module |
| POST | /api/modules/{id}/disable |
JWT+Admin | Disable a module |
Development
Backend
cd backend
go run .
# or
go build -o proxmoxpanel . && ./proxmoxpanel
Environment variables (all optional):
| Variable | Default | Description |
|---|---|---|
DATA_DIR |
/app/data |
Path to persistent data directory |
LISTEN_ADDR |
:3001 |
HTTP listen address |
APP_ENV |
production |
Set to development for verbose logs |
Frontend
cd frontend
npm install
npm run dev # Dev server with proxy to backend at localhost:3001
npm run build # Production build
License
MIT — see LICENSE