core/README.md
enzo 5dbcb1df07 feat: initialisation complète du CORE ProxmoxPanel
Backend Go 1.23+ :
- API REST + WebSocket (chi, gorilla/websocket)
- Authentification PAM via SSH + JWT RS256
- Chiffrement AES-256-GCM pour secrets SQLite
- Pool SSH, client Proxmox REST, hub WebSocket pub/sub
- Système de modules compilés à initialisation conditionnelle
- Audit log, migrations SQLite versionnées

Frontend Vue 3 + Vite + TypeScript :
- Thème Neumorphism sombre/clair (CSS custom properties)
- Wizard d'installation, Dashboard drag-drop, Terminal xterm.js
- Toutes les vues CORE + stubs modules optionnels
- i18n EN/FR (vue-i18n v11)

Infrastructure :
- Docker multi-stage (Go → alpine, Node → nginx)
- docker-compose.yml, .gitattributes, LICENSE MIT, README

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 21:08:53 +01:00

239 lines
8.8 KiB
Markdown

# 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 upgrade` on 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 `PVEAuditor` role is sufficient for metrics)
- Reverse proxy recommended (Traefik, Nginx, Caddy) for HTTPS in production
## Quick Start
```bash
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:
1. **Instance name** and public URL (auto-detected from the HTTP request)
2. **SSH host** — address and port of the Proxmox host (e.g. `192.168.1.10:22`)
3. **SSH credentials** — Linux username and password used for PAM authentication
4. **Proxmox API** — URL and API token (e.g. `https://192.168.1.10:8006`)
5. **Default language**`en` or `fr`
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/chi` v5
- **WebSocket**: `gorilla/websocket`
- **Database**: `modernc.org/sqlite` (pure Go, no CGO)
- **JWT**: `golang-jwt/jwt` v5, 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-theme` on `<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 database
- `keys/jwt.key`, `keys/jwt.pub` — RSA-2048 key pair for JWT signing
- `master.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:
```go
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:
```yaml
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
```bash
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
```bash
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](LICENSE)