Lightweight game-server control panel. Create servers as folders, import game templates (FiveM first), download the Linux server files, start them, and watch live logs — all from one dashboard.
- Node.js 18+
- A Linux host (or WSL) to actually run game servers — the FiveM FXServer binaries are Linux-only. The panel UI itself runs anywhere.
taron PATH (Windows 10+ and all Linux distros ship one).
One command on a fresh VPS (installs Node 20, clones, installs, runs dev):
curl -fsSL https://raw.githubusercontent.com/forzayt/Forza_Panel/main/install.sh | bashOr manually:
npm install
npm run devOpen http://localhost:3000.
npm run build # production build (stop the dev server first — see below)
npm start # serve the production buildLive system overview of the machine running the panel, polling
GET /api/system every 2 seconds: CPU, memory, disk, charts, and system info.
The header pill shows online status plus the machine's public IP
(GET /api/ip via ipify, LAN fallback) with a copy button.
Task-Manager-style live process list, polling GET /api/processes
every 4 seconds: top 60 processes by CPU with per-process CPU %, memory,
PID, sortable columns, and search. Windows uses perf-counter sampling,
Linux uses ps.
Live interfaces with status, MAC, IPv4/IPv6, and per-interface
download/upload rates computed from cumulative counters, polling
GET /api/network every 4 seconds. Windows reads adapter counters via
PowerShell, Linux reads /proc/net/dev.
MySQL card (clickable) for now. Creating a database makes
data/databases/<name>/ with a database.json inside — same
folder-per-item layout as servers, listed straight from disk. Inside a
database, Install Database mirrors the server import flow: a searchable
option list, a confirm step, then apt install mysql-server on Linux
(panel must be root or have passwordless sudo). The button hides once a
MySQL binary is detected. A live MySQL connection, other engines, and user
management arrive in a later phase.
Servers are folders, not database rows. Creating a server makes
data/servers/<name>/ with a server.json inside — that folder is the
server, and the list is read straight from disk.
- Add Server — dialog asks only for a name (letters, numbers, dashes, underscores, max 32). Duplicates are rejected with 409.
- Server cards — each is clickable and opens
/servers/<name>. - Detail page — stats (status, type, created, folder), Import, Start/Stop, Delete, and a live Console.
- Import — searchable template modal (
template/game/*.json), a confirm step, a 5-minute-tolerant Installing animation, then the files land in the server folder. Import also tags the server type (hides Import afterwards — already-imported servers don't show it again). - Start — runs the template's start command detached in the server
folder, logging stdout/stderr to
server.log. The server keeps an open stdin (FXServer quits instantly without one) and launches viaexecso the tracked pid is the real server, which is also what Stop signals. Refuses Linux-only templates on Windows with a clear error, and fails loudly (exit code + log tail) instead of fake-starting when the process dies instantly. - Stop — kills the tracked process, marks the server stopped.
- Console — tails the last 200 lines of
server.logevery 2 seconds with auto-scroll. Only shown for imported servers. - Delete — red button with a type-to-confirm dialog
(
delete <servername>); removes the folder recursively.
{
"id": "fivem",
"game": "GTA V",
"label": "FiveM Server",
"description": "...",
"platforms": ["linux"],
"download": "https://changelogs-live.fivem.net/api/changelog/versions/linux/server",
"serverCfg": ["endpoint_add_tcp ..."],
"start": "bash run.sh +exec server.cfg",
"inputs": [
{
"id": "licenseKey",
"label": "CFX License Key",
"placeholder": "cfxk_xxxxxxxxxxxxxxxxxxxxxxxx",
"help": "...",
"required": true,
"pattern": "^cfxk_[A-Za-z0-9_-]{8,}$",
"appendArg": "+set sv_licenseKey {value}"
}
]
}download— a direct.tar.xz/.tar.gzlink, or a changelog-style JSON endpoint exposingrecommended_download/latest_download(legacy HTML listings are scraped as a last resort).platforms— Start is refused on any otherprocess.platform.serverCfg(optional) — written asserver.cfgafter extraction, on first import only (re-imports never overwrite user edits).{name}is replaced with the server name.inputs(optional) — values the import dialog asks for before installing (e.g. the FiveMsv_licenseKey). Each entry:id,label, optionalplaceholder/help,required, and apatternregex enforced server-side.appendArgis appended tostartat launch with{value}substituted (shell-quoted) — the key is stored in the server'sserver.jsonundersettings, never in the template.
| Method | Route | Purpose |
|---|---|---|
| GET | /api/system |
Live CPU / memory / disk / system info |
| GET | /api/processes |
Live process list (top 60 by CPU) |
| POST | /api/processes/[pid]/kill |
Force-terminate a process |
| GET | /api/network |
Interfaces, addresses, byte counters |
| GET | /api/network/ports |
Listening TCP/UDP ports + owning process |
| GET | /api/ip |
Public IP (ipify), LAN fallback |
| GET | /api/servers |
List servers from data/servers/ |
| POST | /api/servers |
Create a server ({ name }) |
| GET | /api/servers/[name] |
One server |
| DELETE | /api/servers/[name] |
Remove server folder |
| GET | /api/servers/[name]/log?lines=200 |
Tail server.log |
| POST | /api/servers/[name]/import |
Download + extract template ({ templateId, inputs? }) |
| POST | /api/servers/[name]/start |
Run the start command |
| POST | /api/servers/[name]/stop |
Stop the tracked process |
| GET | /api/templates |
List template/game/*.json |
| GET | /api/databases |
List MySQL database folders |
| POST | /api/databases |
Create a database folder ({ name }) |
| GET | /api/databases/[name] |
One database |
| DELETE | /api/databases/[name] |
Remove database folder |
| GET | /api/databases/status |
MySQL installed? + version |
| POST | /api/databases/install |
apt install mysql-server (Linux) |
app/ Routes (dashboard, servers, api) + theme + providers
agent/ ALL machine-touching code lives here — nothing else
runs commands or touches the filesystem
servers.ts Server folders, download/extract, start/stop, logs
system.ts OS metrics, disk probing, LAN IP
templates.ts Template library reader
components/ Dashboard widgets + tailgrids design-system primitives
template/game/ Importable game templates (tracked in git)
data/servers/ One folder per server (runtime data, git-ignored)
utils/ hooks/ types/ Shared helpers
Rule: anything that executes (fs, processes, OS) goes in agent/. UI and
API routes only call into it.
-
EACCES: permission deniedin.next/— some files got created as root (an earliersudorun). Fix ownership once and stop usingsudo(port 3000 needs no privileges):sudo chown -R ubuntu:ubuntu ~/forzapanel rm -rf ~/forzapanel/.next npm run dev
-
next startsays "Could not find a production build" — runnpm run buildfirst;startonly serves an existing build. -
Import 500s — the toast now shows the real reason. Common cause was
tarwarnings on partial archives; exit code 1 is tolerated, 2+ fails. Re-import overwrites partial folders, no cleanup needed. -
Start fails on Windows — expected for Linux templates; deploy the panel on Linux/WSL to run game servers.
-
Empty console — the process died instantly; Start now reports the exit code + log tail instead of pretending. Status badges also self-correct every 5 seconds.
-
next buildfails with/_not-foundor missing chunks — stop the dev server first; dev and build share.next/and corrupt each other. Delete.next/and rebuild clean. -
Hydration error mentioning
data-gr-*attributes — a browser extension (e.g. Grammarly) mutating<body>; suppressed in the layout and harmless.