Overview
AirLink has three layers: the panel (web app), the daemon (per-node agent), and Docker containers (game servers). The panel talks to daemons over HTTP. Daemons talk to Docker over its local API.
Architecture overview
Panel
Express.js web app. Serves HTML via EJS templates and JSON APIs. Stores data in SQLite via Prisma. Runs on Node.js or Bun.
The panel handles:
- User authentication and sessions
- Server creation, deletion, and power control
- File management (via daemon proxy)
- Admin settings, users, nodes, images
- Addon loading and routing
- REST API with scoped keys
Daemon
Bun HTTP server running on each node. Manages Docker containers, files, and SFTP. One daemon per machine.
The daemon handles:
- Container lifecycle (install, start, stop, kill, delete)
- Filesystem operations (list, read, write, upload, download)
- Backup creation and restore
- On-demand SFTP sessions
- Minecraft server queries
HMAC protocol
Every panel-to-daemon request is signed. The flow:
Request authentication
Each request includes:
X-Airlink-Timestamp— ISO timestamp of when the request was signedX-Airlink-Nonce— random string, rejected if seen before (replay protection)X-Airlink-Signature— HMAC-SHA256 ofmethod + path + timestamp + nonce + bodysigned with the daemon keyAuthorization: Basic— base64 encodedAirlink:<daemon-key>
The daemon checks the IP allowlist first, then Basic Auth, then the HMAC signature, then the nonce. If any step fails, the request is rejected.
Request lifecycle
When you click "Start" on a server:
Server start request
SFTP
SFTP sessions are created on demand. The daemon spins up an isolated atmoz/sftp container with:
- A randomly assigned port
- Short-lived credentials
- Access to the server's volume
When the session ends, the container is destroyed. No permanent SFTP server runs on the node.
Addon system
Addons extend the panel without modifying core files. They live in storage/addons/ and are loaded at startup.
Addon loading
Each addon gets:
- An Express router for custom routes
- Prisma access for database queries
- The panel logger
- UI registration (sidebar items, server menu items)
- Migration support for custom tables
See Addon Development for the full reference.
Database
The panel uses Prisma ORM with SQLite by default. MySQL and PostgreSQL are also supported.
Core tables (managed by Prisma migrations):
Users— accounts, passwords, 2FAServers— server configs, resource limits, node assignmentsNodes— daemon addresses, keys, connection statusImages— Docker images, startup commands, env varsFolders— user-created server groupingsApiKeys— scoped API tokensAddonMigration— tracks which addon migrations have run
Addon-created tables are managed by the addon's own migrations and are not part of the Prisma schema.
Port defaults
| Service | Port | Notes |
|---|---|---|
| Panel | 3000 | Configurable via PORT in .env |
| Daemon | 3002 | Configurable per node |
| SFTP | Random | Assigned per session by the daemon |