Architecture
How FeatherPanel is built - FrankenPHP backend, Next.js frontend, Rust async runner, MCP server, MariaDB, Redis, FeatherWings and FeatherQuilld nodes.
On this page
FeatherPanel is split into a panel that you install once and daemons that you install on every machine that runs workloads. The panel never runs game servers or websites itself: it stores state, checks permissions and tells the daemons what to do.
The big picture
Browser / API client / MCP client
│ HTTPS
your reverse proxy (nginx, Apache, Caddy, Cloudflare Tunnel)
│ http://127.0.0.1:4831
┌──────────────────────────── panel host (Docker) ─────────────────────────────┐
│ frontendv2 (Caddy + Next.js) ── /api, /pma, /webmail, /addons ──► backend │
│ │ └─ /mcp, OAuth ──► mcp (Node.js) │ │
│ └─ /vnc-proxy ──► async-runner (Rust) ◄── Redis pub/sub ─────┤ │
│ MariaDB ◄────────┤ Redis │
└──────────────────────────────────────────────────────────────────────┼────────┘
┌───────────────────────────────┬─────────────────────────┘
▼ HTTPS + node token ▼ HTTPS + node token ▼ Proxmox API
FeatherWings (game nodes) FeatherQuilld (web nodes) Proxmox VE (VDS nodes)
Docker, SFTP :2022, API :8080 WebSpaces, proxy, DNS, mail, VMs and LXC containers
SFTP :2222, FTP :21, API :8989
Panel services
The Docker install (docker-compose.yml) runs these containers:
| Service | Image | What it does |
|---|---|---|
frontendv2 | ghcr.io/mythicalltd/featherpanel-frontendv2 | The only published container (host port 4831 by default). A Caddy server in front of the Next.js app that also routes API, MCP and VNC traffic to the other services. |
backend | ghcr.io/mythicalltd/featherpanel-backend | The PHP API on FrankenPHP (Caddy with PHP built in), plus cron and the bundled phpMyAdmin and webmail. |
async-runner | ghcr.io/mythicalltd/featherpanel-async-runner | A Rust worker. Sends queued mail, creates Proxmox VMs and proxies VNC consoles. |
mcp | ghcr.io/mythicalltd/featherpanel-mcp | The Model Context Protocol server for AI assistants. |
mysql | mariadb:latest | The panel database. |
redis | redis:latest | Cache, rate limit and account lockout counters, two-factor challenges, the player status cache and the pub/sub queue for the async runner. |
How requests are routed
The Caddy server inside frontendv2 decides where each request goes:
| Path | Goes to |
|---|---|
/api*, /pma*, /webmail*, /attachments*, /addons*, /components* | backend |
/mcp*, /authorize, /token, /register, /revoke, /oauth*, OAuth /.well-known/* documents | mcp |
/vnc-proxy* | async-runner on port 9100 |
| everything else | Next.js |
Requests may be up to 250 MB. Event streams (/api/mercure and the chatbot streams) are not compressed so they reach the
browser immediately.
Inside the backend
The backend runs PHP on FrankenPHP. By default it uses worker mode: the app boots once and stays in memory, which removes the per-request bootstrap cost. There are two worker pools:
featherpanel-apiserves/api/*. It starts2 x CPUthreads and can grow to3 x CPU(at most 32) under load.featherpanel-slowserves long responses (chatbot streams, file and backup downloads) so a few of them cannot block the rest of the API.
Set FRANKENPHP_WORKER=false to fall back to classic mode. See Cron, workers and runner for
every knob.
The backend also hosts the Mercure hub that pushes live updates to the browser, and runs the cron jobs every minute.
The async runner
The runner listens on three Redis channels:
featherpanel:mail:pendingsends queued e-mail over SMTP, so a slow mail server never slows down a request.featherpanel:vm:pendingcreates VDS instances on Proxmox and reports progress.featherpanel:settings:reloadreloads settings after an admin changes them.
It also serves the browser VNC console for VDS instances at /vnc-proxy.
Daemons
FeatherWings (game servers)
FeatherWings is a Go daemon, forked from Pterodactyl Wings. Each game node runs one. It creates a Docker
container per server, streams the console over a websocket, serves SFTP on port 2022 and takes backups. The panel talks to it
over HTTPS on port 8080 with the node token; Wings calls back to the panel with token_id.token.
A node’s daemon type can also be wings_rs (Calagopus Wings). Those nodes default
to /etc/calagopus-wings/config.yml, /var/lib/calagopus-wings/volumes and the wings systemd unit. The panel keeps a
feature matrix per daemon type (DaemonCapabilities) and hides what a node cannot do:
| Only on FeatherWings nodes | Only on Calagopus Wings nodes |
|---|---|
| modules, live config, host terminal, trash, node firewall, FastDL, diagnostics, Docker disk view, proxy, server import, file sharing, reconcile, container exec | system logs, install abort, directory download, file operation progress, backup browsing, server scripts, live websocket permissions, file fingerprints, paginated file lists, transfer backups, 7z compression |
Both support the core server API, Docker, file search, archive browsing, deauthorize, self update, file history and file collaboration.
FeatherQuilld (web hosting)
FeatherQuilld is a .NET daemon for web nodes. It runs customer WebSpaces in Docker, manages a reverse proxy (Caddy, nginx or Traefik), DNS through PowerDNS, mail through docker-mailserver or mailcow, and SFTP/FTP. Its API listens on port 8989.
Proxmox VE (VDS)
VDS hosting needs no FeatherPanel daemon. The panel stores a Proxmox API token per VDS node and drives Proxmox directly; the async runner does the long-running VM creation. The installer has a Proxmox VNC Agent option that you run on the Proxmox node; it adds noVNC files for PVE token forwarding so the in-panel console works.
Data and state
| What | Where |
|---|---|
| Users, servers, nodes, settings, activity | MariaDB (225 migrations at the time of writing) |
| Secrets in the database (node tokens, API client keys, SMTP password, OIDC secrets and more) | Encrypted with DATABASE_ENCRYPTION_KEY (XChaCha20) |
| Uploaded files, plugins, translations, snapshots, logs | Docker volumes featherpanel_attachments, featherpanel_addons, featherpanel_translations, featherpanel_snapshots, featherpanel_logs |
.env and other config | Volume featherpanel_config (backend/storage/config) |
| Game server files and backups | On each Wings node (/var/lib/featherpanel) |
| WebSpace files and backups | On each Quilld node (/var/lib/featherquilld) |
Optional parts
- phpMyAdmin (
/pma) and webmail (/webmail) are served by the backend. phpMyAdmin is installed withfeatherpanel module install pma. - Telemetry: the
UmamiTelemetryReportercron job sends one event per day with aggregate counts (users, servers, backups, nodes, schedules, webspaces, VMs and similar). The hostname is sent as the fixed stringfeatherpanel. Turn it off with thetelemetrysetting, or force it off for the whole install withUMAMI_ENABLED=false. - Plugins add PHP routes, event listeners, cron jobs and frontend pages. See Plugins.
Frequently asked questions
Only for game servers. Proxmox VDS hosting talks to the Proxmox API directly and web hosting uses FeatherQuilld. A panel with only the web or VDS module enabled needs no Wings node.
Yes. A node's daemon type can be set to Calagopus Wings (wings_rs). The panel keeps a feature matrix per daemon type and hides features a node does not support, such as modules, the node firewall and FastDL on Calagopus Wings nodes.