Files
ferrum/README.md
T
Anand 9b3d093eb8 Expand Needle 2 tool catalog, fix diagnostics, and publish Docker images to GHCR
- Add 48 new MCP/AI-assistant tools covering guest lifecycle, node
  operations, firewall/security, and backup/replication/HA/storage/SDN
  management. Every mutating tool is admin-gated the same way
  guest_power_action already is; migrate/resize/move-disk, node
  reboot/shutdown, disk wipe, cert revocation, and cluster-node removal are
  deliberately left out as being as destructive as a delete.
- ai_chat.go: when a provider (chiefly Needle, a pure tool-router with no
  narrative output of its own) finishes calling tools but returns nothing to
  say, render the tool results themselves as the answer instead of the
  misleading "ran out of tool calls" message.
- needle.go: serialize every request against the shared Needle subprocess
  (it handles one request at a time) to stop concurrent callers from racing
  it, and surface the subprocess's captured output when a request fails
  because it died mid-response, instead of a bare network error.
- Dockerfile: switch the final stage from distroless "static" to "base" —
  the bundled Needle CLI is a dynamically-linked glibc binary and cannot run
  in an image with no libc at all.
- .github/workflows/release.yml: build and push a multi-arch (amd64/arm64)
  Docker image to ghcr.io on every version tag, tagged with the version and
  "latest".
- Dockerfile/README: add OCI image labels and document the published GHCR
  image as the primary Docker install path.
2026-09-09 23:03:54 +05:30

9.5 KiB

Ferrum

Fleet control for Proxmox VE — a single dashboard for every cluster and standalone node you run, with live inventory, dashboards, backups, HA, firewall, alerting, and more.

Screenshots

Captured against a mock Proxmox cluster (prod-cluster: 3 nodes, 16 VMs/LXCs, Ceph + NFS storage) to show the UI populated the way it looks on a real fleet. Click any thumbnail for the full-size image.

Fleet overview dashboard

Fleet overview

Inventory — nodes and guests

Inventory

Topology graph

Topology

Storage pools and Ceph health

Storage

Backup jobs and replication

Backups & replication

HA resources and groups

High availability

Cluster firewall rules

Firewall

Appearance settings — Enterprise, Proxmox-native, and Terminal look & feel

Look & feel — Enterprise / Proxmox-native / Terminal

Connections page

Connections

First-run admin setup

First-run setup

Getting started

go build ./cmd/ferrum
./ferrum -config config.example.yaml

The web UI is served from the same binary (see web/embed.go). For frontend development:

cd web
npm install
npm run dev

On first run, open the UI and create the initial admin account, then add a Proxmox connection (host, port, and either an API token or username/password) from Connections.

Docker

Prebuilt multi-arch (amd64/arm64) images are published to GHCR on every release:

docker run -p 8080:8080 -v ferrum-data:/app/data ghcr.io/anand34577/ferrum:latest

Or build locally from source:

docker build -t ferrum .
docker run -p 8080:8080 -v ferrum-data:/app/data ferrum

Deploying a release build

Every GitHub release ships prebuilt, statically-linked archives for Linux (amd64/arm64), Windows (amd64/arm64), and macOS (amd64/arm64) — no Go toolchain or CGO dependencies needed on the target machine. Each archive bundles the binary, config.example.yaml, and the install script for its OS.

Linux (systemd)

One-liner, same idea as get.docker.com — downloads the latest release for your architecture, verifies its checksum, and installs it as a systemd service:

curl -fsSL https://raw.githubusercontent.com/anand34577/ferrum/main/scripts/get.sh | sudo sh

Pin a specific version with FERRUM_VERSION:

curl -fsSL https://raw.githubusercontent.com/anand34577/ferrum/main/scripts/get.sh | FERRUM_VERSION=v1.2.3 sudo sh

Or do it by hand from a downloaded archive — scripts/get.sh just automates these same steps:

tar -xzf ferrum_*_linux_amd64.tar.gz
cd ferrum_*_linux_amd64
sudo ./install.sh

Either way, this creates a dedicated ferrum system user, installs the binary to /usr/local/bin/ferrum, seeds /etc/ferrum/config.yaml, and enables + starts the ferrum.service systemd unit (packaging/systemd/ferrum.service) — data lives in /var/lib/ferrum, logs go to journalctl -u ferrum -f.

To uninstall, grab scripts/linux/uninstall.sh and run it as root — add -- --purge to also remove config/data:

curl -fsSL https://raw.githubusercontent.com/anand34577/ferrum/main/scripts/linux/uninstall.sh | sudo bash -s --

Windows (Windows Service)

Expand-Archive ferrum_*_windows_amd64.zip
cd ferrum_*_windows_amd64
.\install-service.ps1   # run as Administrator

This installs the binary to %ProgramFiles%\Ferrum, seeds %ProgramData%\Ferrum\config.yaml, and registers a "Ferrum" Windows service — ferrum.exe detects it's running under the Service Control Manager and manages its own start/stop lifecycle, no wrapper (NSSM etc.) needed. Since Windows services don't capture stdout/stderr the way systemd does, logs are written to %ProgramData%\Ferrum\ferrum.log. Uninstall with .\uninstall-service.ps1 (add -Purge to also remove config/data).

Building from source

scripts/build.sh                       # current platform only, output in dist/
scripts/build.sh linux/amd64 windows/amd64
scripts/build.sh all                   # every platform the release workflow builds
.\scripts\build.ps1                    # Windows-native equivalent, current platform only

Both build the frontend, cross-compile with version info baked in (ferrum -version), and package each target as a .tar.gz/.zip with its install script — the same thing .github/workflows/release.yml runs when a vX.Y.Z tag is pushed, publishing the resulting archives (and a checksums.txt) as GitHub Release assets.

Configuration

Copy config.example.yaml to config.yaml and adjust as needed, or set the equivalent FERRUM_* environment variables (see the comments in that file for the full list, including SQLite/PostgreSQL, TLS cookie behavior, reverse-proxy support, and optional OIDC single sign-on).

Everything else — notifications, SSO details, security policy, system settings, AI providers, and the REST API/MCP enable switches below — is configured from the admin Settings UI once Ferrum is running, not from environment variables.

Built-in LLM (Needle 2)

The AI Assistant and MCP tool-calling loop can use any OpenAI-chat-completions-compatible provider (OpenAI, Ollama, LM Studio, LocalAI, OpenRouter, ...) configured under Settings > AI Providers. There's also an optional zero-config, no-API-key, fully local option backed by Needle 2 — a small (45M-parameter) tool-calling model that runs as a self-contained CLI binary with no GPU and no network access required at inference time.

Needle 2 is Apache-2.0 licensed, so on Windows, Linux, and macOS (amd64 or arm64) Ferrum ships its official CLI binary baked into the ferrum binary itself (internal/needle/bundled_*.go, one per platform via go:embed) — nothing to download, nothing to configure. On a fresh install (no AI provider configured yet), Ferrum extracts it to a cache file and registers it automatically as the default assistant the first time it starts — no manual "Add provider" step needed. If you've already configured a provider, or want to add/re-add it yourself, use Settings > AI Providers > "Add provider" > the Needle 2 (built-in, local) preset.

On any other platform (32-bit, RISC-V, Windows/ARM64, ...) there's no bundled binary — Ferrum still never fetches executable content from the network on its own. To enable it there:

  1. Download the needle CLI binary for your platform from the Needle 2 files.
  2. Point Ferrum at it: set FERRUM_NEEDLE_BIN=/path/to/needle (or needleBinPath in config.yaml) before starting Ferrum. This also overrides the bundled binary on a supported platform, if you'd rather run a different build.

Ferrum starts the binary itself (as a local subprocess, 127.0.0.1-only) the first time it's used, and stops it on shutdown. If no binary is bundled for the platform and FERRUM_NEEDLE_BIN isn't set (or doesn't exist), this provider simply isn't usable — every other provider is unaffected.

API access, MCP, and audit logging

Any user can generate long-lived API keys under Profile > API Keys — scoped to either the general REST API (Authorization: Bearer <key> against /api/v1/..., for 3rd-party integrations and scripts) or the MCP endpoint only (/mcp, for Claude Code/Desktop or any other MCP-capable agent — see Profile > MCP integration for ready-to-paste config). Both surfaces are off by default and must be turned on by an admin under Settings > API & MCP, which also caps how many tool calls the AI Assistant's agent loop can make per message. Every mutating action — through the UI, the REST API, or MCP — is recorded with who, what, and when under Audit Log (admin-only).

License

MIT