docker-compose.panel.yml deploys every service from a published image. A control panel writes only a compose file and an .env into its project directory, so the build: stanzas of docker-compose.yml cannot resolve their context there. CI pushes api, migrate, web and daemon images to the Gitea container registry on v* tags. The migrate stage ships as its own image because the panel compose runs it as a one-shot service before the API starts. The web port is named HOST_PORT: panels reverse-proxy "the" port of an installation and need to know which one that is when a stack publishes more than one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GamePanel
Modern, open-source game server management panel built with a multi-tenant SaaS architecture. Inspired by Pterodactyl, enhanced with features like plugin management, visual task scheduler, live player tracking, and an in-browser config editor.
Features
Core
- Multi-Tenant Organizations — Isolated environments with role-based access control (Admin / User + custom JSONB permissions)
- Docker Container Management — Full lifecycle: create, start, stop, restart, kill, delete
- Multi-Node Architecture — Distribute game servers across multiple daemon nodes with health monitoring
- Live Console — xterm.js terminal with Socket.IO streaming, command history support
- File Manager — Browse, view, edit, create, and delete server files with path jail security
- Server Creation Wizard — 3-step guided flow: Basic Info, Node & Allocation, Resources
Game-Specific
- Config Editor — Tab-based UI with parsers for
.properties,.json,.yaml, and Source Engine.cfgformats - Plugin Management — Spiget API integration for Minecraft, manual install for other games, toggle/uninstall
- Player Tracking — Live player list via RCON protocol (Minecraft
list, CS2status)
Advanced
- Scheduled Tasks — Visual scheduler with interval, daily, weekly, and cron expression support
- Backup System — Create, restore, lock/unlock, delete backups with CDN storage integration
- Audit Logging — Track all actions across the panel with user, server, and IP metadata
Operations
- Rate Limiting — Configurable per-window request limits
- Security Headers — Helmet.js with CSP, XSS protection, content-type sniffing prevention
- Health Checks — Built-in endpoints for all services
- CI/CD — GitHub Actions pipeline for lint, test, and Docker build
Architecture
Browser ─── HTTPS + Socket.IO ──→ Web (React SPA / nginx)
│
REST + WS
│
API (Fastify + JWT)
│ │
PostgreSQL gRPC (protobuf)
│
Daemon (Rust + tonic) × N nodes
│
Docker API
│
Game Containers
The API acts as a gateway between the frontend and daemon nodes. The frontend never communicates directly with daemons.
Tech Stack
| Component | Technology |
|---|---|
| Monorepo | Turborepo + pnpm |
| Frontend | React 19 + Vite 6 + Tailwind CSS 3 + shadcn/ui |
| Backend API | Fastify 5 + TypeBox validation |
| Daemon | Rust + tonic gRPC + bollard (Docker) + tokio |
| Database | PostgreSQL 16 + Drizzle ORM |
| Auth | JWT (access + refresh) + Argon2id |
| Realtime | Socket.IO (frontend ↔ API) |
| Panel ↔ Daemon | gRPC with protobuf |
| Containers | Docker |
| CI/CD | GitHub Actions |
Monorepo Structure
source-gamepanel/
├── apps/
│ ├── api/ # Fastify REST API
│ │ ├── src/
│ │ │ ├── index.ts # App entry, plugin registration
│ │ │ ├── plugins/ # DB, auth plugins
│ │ │ ├── lib/ # Errors, JWT, permissions, pagination,
│ │ │ │ config parsers, Spiget client, schedule utils
│ │ │ └── routes/
│ │ │ ├── auth/ # Register, login, refresh, logout, me
│ │ │ ├── organizations/ # CRUD + members
│ │ │ ├── nodes/ # CRUD + allocations
│ │ │ ├── servers/ # CRUD + power, config, plugins, backups, schedules
│ │ │ └── admin/ # Users, games, audit logs (super admin)
│ │ └── Dockerfile
│ │
│ ├── web/ # React SPA
│ │ ├── src/
│ │ │ ├── components/
│ │ │ │ ├── ui/ # 13 shadcn/ui components
│ │ │ │ ├── layout/ # AppLayout, ServerLayout, Sidebar, Header
│ │ │ │ ├── server/ # PowerControls
│ │ │ │ └── error-boundary.tsx
│ │ │ ├── pages/
│ │ │ │ ├── auth/ # Login, Register
│ │ │ │ ├── dashboard/ # Stats + server list
│ │ │ │ ├── server/ # Console, Files, Config, Plugins,
│ │ │ │ │ Backups, Schedules, Players, Settings
│ │ │ │ ├── servers/ # Create wizard
│ │ │ │ ├── nodes/ # List + detail (health dashboard)
│ │ │ │ ├── organizations/ # Org list + create
│ │ │ │ ├── admin/ # Users, Games, Audit logs
│ │ │ │ └── settings/ # Members
│ │ │ ├── lib/ # API client, socket, utils
│ │ │ ├── stores/ # Zustand auth store
│ │ │ └── hooks/ # Theme hook
│ │ ├── nginx.conf
│ │ └── Dockerfile
│ │
│ └── daemon/ # Rust daemon
│ ├── src/
│ │ ├── main.rs # gRPC server, heartbeat, scheduler init
│ │ ├── config.rs # YAML config loader
│ │ ├── auth.rs # gRPC token interceptor
│ │ ├── grpc/ # Service implementations
│ │ ├── docker/ # Container lifecycle (bollard)
│ │ ├── server/ # State machine, manager
│ │ ├── filesystem/ # Path jail, CRUD operations
│ │ ├── game/ # RCON client, Minecraft, CS2 modules
│ │ ├── scheduler/ # Task polling + execution
│ │ └── backup/ # tar.gz, CDN upload/download, restore
│ ├── Cargo.toml
│ └── Dockerfile
│
├── packages/
│ ├── database/ # Drizzle schema + migrations + seed
│ │ └── src/schema/ # 10 tables: users, orgs, nodes, servers,
│ │ allocations, games, backups, plugins,
│ │ schedules, audit_logs
│ ├── shared/ # Types, permissions, roles
│ ├── proto/ # daemon.proto (gRPC service definition)
│ └── ui/ # Base UI utilities (cn, cva)
│
├── docker-compose.yml # Full production stack
├── docker-compose.dev.yml # Dev: PostgreSQL + Redis only
├── daemon-config.yml # Daemon configuration template
├── .env.example # Environment variables reference
├── .github/workflows/ci.yml # CI/CD pipeline
├── turbo.json
└── pnpm-workspace.yaml
Supported Games
| Game | Docker Image | Default Port | Config Format | Plugin Support |
|---|---|---|---|---|
| Minecraft: Java Edition | itzg/minecraft-server |
25565 | .properties, .yml, .json |
Spiget API + manual |
| Counter-Strike 2 | cm2network/cs2 |
27015 | Source .cfg (keyvalue) |
Manual |
| Minecraft: Bedrock Edition | itzg/minecraft-bedrock-server |
19132 | .properties |
— |
| Terraria | ryshe/terraria |
7777 | keyvalue | — |
| Rust | didstopia/rust-server |
28015 | — | — |
| Satisfactory | wolveix/satisfactory-server |
7777 + 8888/tcp | — | — |
| FiveM | spritsail/fivem:stable |
30120 | server.cfg (keyvalue-style) |
— |
| ARK: Survival Evolved | hermsi/ark-server |
7777/udp + 7778/udp + 27015/udp + 27020/tcp | GameUserSettings.ini, Game.ini |
— |
Most games only need a database seed entry: the container mount point, the
in-game stop command and the shutdown budget are all columns on games, so no
daemon change is required for a new image. Games whose process ignores stdin
(Source engine, ARK) get their console commands over RCON automatically.
API Endpoints
Auth
| Method | Path | Description |
|---|---|---|
| POST | /api/auth/register |
Create account |
| POST | /api/auth/login |
Login (returns JWT + refresh cookie) |
| POST | /api/auth/refresh |
Refresh access token |
| POST | /api/auth/logout |
Invalidate session |
| GET | /api/auth/me |
Current user profile |
Organizations
| Method | Path | Description |
|---|---|---|
| GET | /api/organizations |
List user's orgs |
| POST | /api/organizations |
Create org |
| GET/PATCH/DELETE | /api/organizations/:orgId |
Org CRUD |
| GET/POST/DELETE | /api/organizations/:orgId/members |
Member management |
Servers
| Method | Path | Description |
|---|---|---|
| GET/POST | .../servers |
List / create |
| GET/PATCH/DELETE | .../servers/:serverId |
Server CRUD |
| POST | .../servers/:serverId/power |
Power actions (start/stop/restart/kill) |
| GET/PUT | .../servers/:serverId/config |
Config read/write |
| GET/POST/DELETE | .../servers/:serverId/plugins |
Plugin management |
| GET/POST/DELETE | .../servers/:serverId/backups |
Backup management |
| POST | .../servers/:serverId/backups/:id/restore |
Restore backup |
| GET/POST/PATCH/DELETE | .../servers/:serverId/schedules |
Scheduled tasks |
Admin (Super Admin only)
| Method | Path | Description |
|---|---|---|
| GET | /api/admin/users |
All users |
| GET/POST | /api/admin/games |
Game management |
| GET | /api/admin/audit-logs |
Audit trail |
Permission System
Dot-notation permissions with hybrid RBAC (role defaults + per-user JSONB overrides):
server.create server.read server.update server.delete
console.read console.write
files.read files.write files.delete files.archive
backup.read backup.create backup.restore backup.delete backup.manage
schedule.read schedule.manage
plugin.read plugin.manage
config.read config.write
power.start power.stop power.restart power.kill
node.read node.manage
org.settings org.members
subuser.read subuser.manage
Quick Start
See INSTALLATION.md for detailed setup instructions.
# Clone
git clone https://github.com/your-org/source-gamepanel.git
cd source-gamepanel
# Environment
cp .env.example .env
# Edit .env — set JWT_SECRET and JWT_REFRESH_SECRET
# Start infrastructure
docker compose -f docker-compose.dev.yml up -d
# Install dependencies
pnpm install
# Run migrations and seed
pnpm db:migrate
pnpm db:seed
# Start development
pnpm dev
Open http://localhost:5173 — login with admin@gamepanel.local / admin123.
Production Deployment
git clone https://github.com/your-org/source-gamepanel.git
cd source-gamepanel
# Generates .env with fresh secrets + daemon-config.yml, creates data dirs
./scripts/install.sh
# Builds and starts everything; schema migration and seeding run automatically
docker compose up -d --build
Open http://<server-ip> and sign in with admin@gamepanel.local / admin123.
The panel serves plain HTTP on WEB_PORT (default 80) and does not manage
TLS or domains — put your own reverse proxy in front of it and set
CORS_ORIGIN to the origin users actually open. See
INSTALLATION.md for Caddy and
nginx examples.
Development
pnpm dev # Start all services (API + Web + DB)
pnpm build # Build all packages
pnpm lint # Lint all packages
pnpm format # Format with Prettier
pnpm db:studio # Open Drizzle Studio (DB browser)
pnpm db:generate # Generate migration files
pnpm db:migrate # Apply migrations
pnpm db:seed # Seed admin user + games
# Daemon (separate terminal)
cd apps/daemon
cargo run # Requires protoc installed
cargo test # Run unit tests
cargo clippy # Lint Rust code
License
This project is private. All rights reserved.