View .md

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:

ServiceImageWhat it does
frontendv2ghcr.io/mythicalltd/featherpanel-frontendv2The 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.
backendghcr.io/mythicalltd/featherpanel-backendThe PHP API on FrankenPHP (Caddy with PHP built in), plus cron and the bundled phpMyAdmin and webmail.
async-runnerghcr.io/mythicalltd/featherpanel-async-runnerA Rust worker. Sends queued mail, creates Proxmox VMs and proxies VNC consoles.
mcpghcr.io/mythicalltd/featherpanel-mcpThe Model Context Protocol server for AI assistants.
mysqlmariadb:latestThe panel database.
redisredis:latestCache, 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:

PathGoes to
/api*, /pma*, /webmail*, /attachments*, /addons*, /components*backend
/mcp*, /authorize, /token, /register, /revoke, /oauth*, OAuth /.well-known/* documentsmcp
/vnc-proxy*async-runner on port 9100
everything elseNext.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-api serves /api/*. It starts 2 x CPU threads and can grow to 3 x CPU (at most 32) under load.
  • featherpanel-slow serves 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:pending sends queued e-mail over SMTP, so a slow mail server never slows down a request.
  • featherpanel:vm:pending creates VDS instances on Proxmox and reports progress.
  • featherpanel:settings:reload reloads 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 nodesOnly on Calagopus Wings nodes
modules, live config, host terminal, trash, node firewall, FastDL, diagnostics, Docker disk view, proxy, server import, file sharing, reconcile, container execsystem 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

WhatWhere
Users, servers, nodes, settings, activityMariaDB (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, logsDocker volumes featherpanel_attachments, featherpanel_addons, featherpanel_translations, featherpanel_snapshots, featherpanel_logs
.env and other configVolume featherpanel_config (backend/storage/config)
Game server files and backupsOn each Wings node (/var/lib/featherpanel)
WebSpace files and backupsOn each Quilld node (/var/lib/featherquilld)

Optional parts

  • phpMyAdmin (/pma) and webmail (/webmail) are served by the backend. phpMyAdmin is installed with featherpanel module install pma.
  • Telemetry: the UmamiTelemetryReporter cron 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 string featherpanel. Turn it off with the telemetry setting, or force it off for the whole install with UMAMI_ENABLED=false.
  • Plugins add PHP routes, event listeners, cron jobs and frontend pages. See Plugins.

Frequently asked questions

Does FeatherPanel need FeatherWings?

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.

Can FeatherPanel use Calagopus Wings instead of FeatherWings?

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.