Stop remote processes with pkill -f before upload so long binary names are matched and busy executables can be overwritten.
129 lines
5.0 KiB
Markdown
129 lines
5.0 KiB
Markdown
# ClusterCanvas
|
||
|
||
A web-based dashboard for managing Proxmox VMs, LXC containers, and Docker. After configuration it discovers hosts and shows per‑instance details like hostname, storage and RAM usage, and status. From the same interface you can view logs, run updates, deploy changes, and perform other routine maintenance tasks.
|
||
|
||
## Layout
|
||
|
||
| Path | Role |
|
||
|------|------|
|
||
| `service/` | Go HTTP API |
|
||
| `webui/` | Vite + React + TypeScript SPA |
|
||
|
||
## Prerequisites
|
||
|
||
- Go 1.22+ (toolchain may download a newer Go as needed)
|
||
- Node.js 20+ and npm
|
||
|
||
## Configuration
|
||
|
||
Service config lives under **`/etc/ClusterCanvas/`** by default:
|
||
|
||
| File | Purpose |
|
||
|------|---------|
|
||
| `settings.json` | Plain base settings (non-secret), including setup/network/security/groups |
|
||
| `passwords.enc` | AES-GCM encrypted user credentials (argon2id hashes, TOTP secrets) |
|
||
| `sessions.enc` | AES-GCM encrypted session store |
|
||
| `secrets.enc` | AES-GCM encrypted JSON secrets (integrations, etc.) |
|
||
|
||
**Config directory precedence** (highest first):
|
||
|
||
1. `-configdir` flag — e.g. `./bin/clustercanvas-server -configdir="~/.myconfigs"`
|
||
2. `CLUSTERCANVAS_CONFIG_DIR` environment variable
|
||
3. `/etc/ClusterCanvas`
|
||
|
||
A leading `~/` in the path is expanded to the user home directory.
|
||
|
||
**Secrets encryption key:** set `CLUSTERCANVAS_CONFIG_KEY` to a base64-encoded 16-, 24-, or 32-byte key (required for first-run setup and login):
|
||
|
||
```bash
|
||
openssl rand -base64 32
|
||
export CLUSTERCANVAS_CONFIG_KEY='…paste output…'
|
||
```
|
||
|
||
For a one-off shell session you can also prefix the command:
|
||
|
||
```bash
|
||
CLUSTERCANVAS_CONFIG_KEY="$(openssl rand -base64 32)" make service
|
||
# or with make dev:
|
||
export CLUSTERCANVAS_CONFIG_KEY="$(openssl rand -base64 32)"
|
||
make dev
|
||
```
|
||
|
||
Keep the same key across restarts if you already ran setup — changing it makes existing `passwords.enc` / `sessions.enc` unreadable.
|
||
|
||
### First-run setup
|
||
|
||
On a clean install (`setup_completed` is false / missing), the web UI opens a setup wizard instead of the dashboard. It creates the admin user, Administrators group, network settings (listen address, optional public hostname, IP allow/deny lists), and security policy, then requires sign-in.
|
||
|
||
Session cookies use the `__Host-ClusterCanvas-Session` name with `Secure`, `HttpOnly`, `SameSite=Strict`, and `Path=/` (no `Domain`). Production should set a **public hostname** and terminate TLS at a reverse proxy so browsers reach the UI over HTTPS. Listen address changes apply on the next process restart.
|
||
|
||
## Run
|
||
|
||
Start API and web UI together (API `:8080`, UI `:5173`; Ctrl+C stops both):
|
||
|
||
```bash
|
||
make dev
|
||
```
|
||
|
||
Or start them separately:
|
||
|
||
```bash
|
||
make service # API on :8080 (override with PORT)
|
||
make webui # UI on :5173 (proxies /health and /api)
|
||
```
|
||
|
||
Custom config directory for the API:
|
||
|
||
```bash
|
||
cd service && go run ./cmd/server -configdir="$HOME/.myconfigs"
|
||
```
|
||
|
||
Optional: set `VITE_API_BASE_URL` (defaults to `http://localhost:8080`) if you call the API without the Vite proxy. An empty value means same-origin requests (used by `make remotedev`).
|
||
|
||
## Remote dev (VM without SDKs)
|
||
|
||
Build on your machine, copy runnables over SSH, and run **both** processes on a remote host (no Go/Node required there—only OpenSSH).
|
||
|
||
Prepare host/user once (recommended):
|
||
|
||
```bash
|
||
cp remotedev.mk.example remotedev.mk
|
||
# edit REMOTEDEV_USER and REMOTEDEV_HOST in remotedev.mk
|
||
make remotedev
|
||
```
|
||
|
||
Or pass them on the CLI:
|
||
|
||
```bash
|
||
REMOTEDEV_USER=youruser REMOTEDEV_HOST=192.168.1.50 make remotedev
|
||
# or combined: REMOTEDEV_HOST=youruser@192.168.1.50 make remotedev
|
||
```
|
||
|
||
| Env | Default | Meaning |
|
||
|-----|---------|---------|
|
||
| `REMOTEDEV_HOST` | _(required)_ | Host/IP, `user@host`, or an SSH config Host alias |
|
||
| `REMOTEDEV_USER` | _(optional)_ | Username; combined as `user@host` when set |
|
||
| `REMOTEDEV_DIR` | `clustercanvas-remotedev` | Remote directory (`~/…` is fine; relative paths are under the remote home) |
|
||
| `REMOTEDEV_CONFIG_KEY` | _(baked-in remotedev key)_ | Dev-only `CLUSTERCANVAS_CONFIG_KEY` exported on the VM (override in `remotedev.mk`) |
|
||
| `PORT` | `8080` | API listen port on the VM (all interfaces) |
|
||
| `WEBUI_PORT` | `5173` | Web UI listen port on the VM (all interfaces) |
|
||
|
||
What lands on the VM: `clustercanvas-server`, `clustercanvas-webui`, and `web/` (built SPA). Config is stored under `$(REMOTEDEV_DIR)/config` with the remotedev encryption key so the setup wizard works without extra env setup. Transfer uses `scp` (OpenSSH only on the remote—no `rsync` required). Re-running `make remotedev` stops any previous instance on the VM before uploading so binaries are not busy. The webui binary serves the SPA and proxies `/api` and `/health` to the API. Open `http://<vm-ip>:5173`. Ctrl+C stops both remote processes. A reverse proxy in front of these ports is optional and separate.
|
||
|
||
**Do not use `REMOTEDEV_CONFIG_KEY` (or its default) in production** — generate a unique key with `openssl rand -base64 32` instead.
|
||
## Test
|
||
|
||
```bash
|
||
make test
|
||
```
|
||
|
||
This runs `go test ./...` in `service/` and Vitest in `webui/`.
|
||
|
||
## Build
|
||
|
||
```bash
|
||
make build
|
||
```
|
||
|
||
Produces `bin/clustercanvas-server`, `bin/clustercanvas-webui`, and `webui/dist/`.
|