15 KiB
Installation Guide
This guide covers three deployment methods:
- Development Setup — for local development
- Docker Production — single-command deployment with Docker Compose
- Manual Production — step-by-step on Ubuntu 22.04+
Prerequisites
All Methods
- Git
- A PostgreSQL 16+ database (or use the included Docker Compose)
Development
- Node.js 20+ (nodejs.org)
- pnpm 9.15+ (
corepack enable && corepack prepare pnpm@9.15.4 --activate) - Rust 1.83+ (rustup.rs)
- protoc (Protocol Buffers compiler) — required for the daemon's gRPC build
- Docker — for running PostgreSQL and Redis locally
Docker Production
- Docker 24+ with Docker Compose v2
- At least 2 GB RAM and 10 GB disk for the panel itself
- Additional resources for game servers on daemon nodes
1. Development Setup
1.1 Clone and Install
git clone https://github.com/your-org/source-gamepanel.git
cd source-gamepanel
pnpm install
1.2 Environment Configuration
cp .env.example .env
Edit .env and set at minimum:
# Generate secure secrets:
# node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
JWT_SECRET=<your-64-byte-hex>
JWT_REFRESH_SECRET=<another-64-byte-hex>
# Database (defaults work with docker-compose.dev.yml)
DATABASE_URL=postgresql://gamepanel:gamepanel@localhost:5432/gamepanel
1.3 Start Infrastructure
# Start PostgreSQL + Redis
docker compose -f docker-compose.dev.yml up -d
1.4 Database Setup
# Generate migration files (if schema changed)
pnpm db:generate
# Apply migrations to create all tables
pnpm db:migrate
# Seed admin user and default games
pnpm db:seed
After seeding, you'll have:
- Admin account:
admin@gamepanel.local/admin123 - Games: Minecraft Java, CS2, Minecraft Bedrock, Terraria, Rust
1.5 Start Development Servers
# Start API (port 3000) + Web (port 5173) via Turborepo
pnpm dev
The web dev server proxies /api and /socket.io requests to the API automatically.
Open http://localhost:5173 in your browser.
1.6 Daemon (Optional)
The Rust daemon manages Docker containers on game server nodes. For development you can run it locally:
# Ensure protoc is installed
protoc --version # Should show libprotoc 3.x or higher
# If not installed:
# Ubuntu: sudo apt install protobuf-compiler
# macOS: brew install protobuf
# Windows: choco install protoc (or download from GitHub releases)
cd apps/daemon
cargo run
The daemon reads its config from /etc/gamepanel/config.yml or the path in DAEMON_CONFIG env var. For development, it falls back to defaults (API at localhost:3000, dev token).
1.7 Useful Commands
pnpm build # Build all packages
pnpm lint # ESLint across all packages
pnpm format # Prettier format
pnpm format:check # Check formatting without modifying
pnpm db:studio # Open Drizzle Studio (visual DB browser)
# Daemon
cd apps/daemon
cargo test # Run unit tests (3 tests: Minecraft parser, CS2 parser)
cargo clippy # Rust linter
cargo build --release # Production build
2. Docker Production Deployment
2.1 Prepare Environment
git clone https://github.com/your-org/source-gamepanel.git
cd source-gamepanel
cp .env.example .env
Edit .env with production values:
# REQUIRED — Generate unique secrets for each!
JWT_SECRET=<generate-with-openssl-rand-hex-64>
JWT_REFRESH_SECRET=<generate-another-secret>
# Database
DB_USER=gamepanel
DB_PASSWORD=<strong-random-password>
DB_NAME=gamepanel
# Redis
REDIS_PASSWORD=<strong-random-password>
# Networking
CORS_ORIGIN=https://panel.yourdomain.com
WEB_PORT=80
API_PORT=3000
# Rate limiting
RATE_LIMIT_MAX=100
RATE_LIMIT_WINDOW_MS=60000
2.2 Configure Daemon
Edit daemon-config.yml:
api_url: "http://api:3000"
node_token: "<generate-a-secure-token>"
grpc_port: 50051
data_path: "/var/lib/gamepanel/servers"
backup_path: "/var/lib/gamepanel/backups"
docker:
socket: "/var/run/docker.sock"
network: "gamepanel_nw"
network_subnet: "172.18.0.0/16"
2.3 Build and Start
# Build and start all services
docker compose up -d --build
This starts 5 services:
| Service | Port | Description |
|---|---|---|
postgres |
5432 | PostgreSQL database |
redis |
6379 | Rate limiting & cache |
api |
3000 | Fastify REST API |
web |
80 | nginx + React SPA |
daemon |
50051 | Rust gRPC daemon |
2.4 Initialize Database
# Run migrations
docker compose exec api node -e "
import('drizzle-kit').then(m => console.log('Use drizzle-kit migrate'))
"
# Or use the pnpm scripts with the container's DATABASE_URL
docker compose exec api sh -c 'cd /app && node apps/api/dist/index.js'
For the initial setup, the easiest approach is:
# Run migrations from your host machine pointed at the Docker PostgreSQL
DATABASE_URL=postgresql://gamepanel:<your-password>@localhost:5432/gamepanel pnpm db:migrate
DATABASE_URL=postgresql://gamepanel:<your-password>@localhost:5432/gamepanel pnpm db:seed
2.5 Verify
# Check all services are healthy
docker compose ps
# Test API health
curl http://localhost:3000/api/health
# {"status":"ok","timestamp":"2025-..."}
# Test web
curl -s http://localhost | head -5
# <!DOCTYPE html>...
2.6 Monitoring
# View logs
docker compose logs -f api
docker compose logs -f daemon
docker compose logs -f web
# Restart a service
docker compose restart api
# Update to latest
git pull
docker compose up -d --build
3. Manual Production Setup (Ubuntu 22.04+)
3.1 System Dependencies
sudo apt update && sudo apt upgrade -y
# Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs
# pnpm
corepack enable
corepack prepare pnpm@9.15.4 --activate
# PostgreSQL 16
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
sudo apt install -y postgresql-16
# Redis
sudo apt install -y redis-server
# Docker (for game containers)
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
# Rust (for daemon)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
# protoc (for gRPC)
sudo apt install -y protobuf-compiler
# nginx (reverse proxy)
sudo apt install -y nginx certbot python3-certbot-nginx
3.2 Database Setup
sudo -u postgres psql << 'EOF'
CREATE USER gamepanel WITH PASSWORD 'your-strong-password';
CREATE DATABASE gamepanel OWNER gamepanel;
GRANT ALL PRIVILEGES ON DATABASE gamepanel TO gamepanel;
EOF
3.3 Redis Configuration
sudo sed -i 's/# requirepass foobared/requirepass your-redis-password/' /etc/redis/redis.conf
sudo systemctl restart redis-server
3.4 Application Setup
# Clone
cd /opt
sudo git clone https://github.com/your-org/source-gamepanel.git
sudo chown -R $USER:$USER source-gamepanel
cd source-gamepanel
# Install
pnpm install
# Environment
cp .env.example .env
nano .env # Set all production values
# Build
pnpm build
# Database
pnpm db:migrate
pnpm db:seed
# Build daemon
cd apps/daemon
cargo build --release
sudo cp target/release/gamepanel-daemon /usr/local/bin/
3.5 Daemon Configuration
sudo mkdir -p /etc/gamepanel /var/lib/gamepanel/{servers,backups}
sudo tee /etc/gamepanel/config.yml << 'EOF'
api_url: "http://127.0.0.1:3000"
node_token: "generate-a-secure-token-here"
grpc_port: 50051
data_path: "/var/lib/gamepanel/servers"
backup_path: "/var/lib/gamepanel/backups"
docker:
socket: "/var/run/docker.sock"
network: "gamepanel_nw"
network_subnet: "172.18.0.0/16"
EOF
3.6 Systemd Services
API Service:
sudo tee /etc/systemd/system/gamepanel-api.service << 'EOF'
[Unit]
Description=GamePanel API
After=network.target postgresql.service redis-server.service
Requires=postgresql.service
[Service]
Type=simple
User=gamepanel
WorkingDirectory=/opt/source-gamepanel
ExecStart=/usr/bin/node apps/api/dist/index.js
Restart=always
RestartSec=5
EnvironmentFile=/opt/source-gamepanel/.env
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
EOF
Daemon Service:
sudo tee /etc/systemd/system/gamepanel-daemon.service << 'EOF'
[Unit]
Description=GamePanel Daemon
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
ExecStart=/usr/local/bin/gamepanel-daemon
Restart=always
RestartSec=5
Environment=DAEMON_CONFIG=/etc/gamepanel/config.yml
Environment=RUST_LOG=info
[Install]
WantedBy=multi-user.target
EOF
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now gamepanel-api
sudo systemctl enable --now gamepanel-daemon
3.7 Web Build + nginx
# Build the SPA
cd /opt/source-gamepanel/apps/web
pnpm build # outputs to dist/
# Copy to nginx
sudo mkdir -p /var/www/gamepanel
sudo cp -r dist/* /var/www/gamepanel/
nginx site config:
sudo tee /etc/nginx/sites-available/gamepanel << 'EOF'
server {
listen 80;
server_name panel.yourdomain.com;
root /var/www/gamepanel;
index index.html;
# Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
# API proxy
location /api/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Socket.IO
location /socket.io/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
# Static assets
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# SPA fallback
location / {
try_files $uri $uri/ /index.html;
}
}
EOF
sudo ln -sf /etc/nginx/sites-available/gamepanel /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
3.8 TLS with Let's Encrypt
sudo certbot --nginx -d panel.yourdomain.com
Certbot will automatically configure nginx for HTTPS and set up auto-renewal.
3.9 Firewall
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 50051/tcp # gRPC (daemon)
# Open game server port ranges as needed:
sudo ufw allow 25565/tcp # Minecraft
sudo ufw allow 27015/tcp # CS2
sudo ufw enable
Post-Installation
First Login
- Open your panel URL in a browser
- Login with:
admin@gamepanel.local/admin123 - Immediately change the admin password via account settings
Create Your First Server
- Create an Organization — Click "New Organization" on the home page
- Add a Node — Go to Nodes, add your daemon node (FQDN + ports)
- Add Allocations — Assign IP:port pairs to the node
- Create a Server — Use the creation wizard: pick a game, node, and resources
- Start the Server — Use the power controls on the console page
Adding a Remote Daemon Node
On the remote machine:
# Install Docker
curl -fsSL https://get.docker.com | sh
# Install the daemon binary
scp user@panel-server:/usr/local/bin/gamepanel-daemon /usr/local/bin/
# Configure
mkdir -p /etc/gamepanel /var/lib/gamepanel/{servers,backups}
cat > /etc/gamepanel/config.yml << EOF
api_url: "https://panel.yourdomain.com"
node_token: "<token-from-panel>"
grpc_port: 50051
EOF
# Create systemd service (same as above)
# Start it
systemctl enable --now gamepanel-daemon
Then add the node in the panel with the remote machine's FQDN.
Troubleshooting
API won't start
- Check
DATABASE_URLis correct and PostgreSQL is running - Ensure migrations have been applied:
pnpm db:migrate - Check logs:
journalctl -u gamepanel-api -fordocker compose logs api
Daemon can't connect
- Verify
api_urlin daemon config points to the API - Check
node_tokenmatches what's stored in the panel's nodes table - Ensure the daemon's gRPC port (50051) is open
Web shows blank page
- Build the SPA:
pnpm --filter @source/web build - Check nginx config:
sudo nginx -t - Verify API proxy is working:
curl http://localhost:3000/api/health
Docker permission denied
- Ensure the daemon user is in the
dockergroup:usermod -aG docker <user> - Or run the daemon with appropriate privileges
protoc not found (daemon build)
- Ubuntu:
sudo apt install protobuf-compiler - macOS:
brew install protobuf - Or download from github.com/protocolbuffers/protobuf/releases
Updating
Docker
cd /opt/source-gamepanel
git pull
docker compose up -d --build
Manual
cd /opt/source-gamepanel
git pull
pnpm install
pnpm build
pnpm db:migrate
# Rebuild daemon
cd apps/daemon && cargo build --release
sudo cp target/release/gamepanel-daemon /usr/local/bin/
# Rebuild web
cd ../web && pnpm build
sudo cp -r dist/* /var/www/gamepanel/
# Restart services
sudo systemctl restart gamepanel-api gamepanel-daemon
sudo systemctl reload nginx
Environment Variables Reference
| Variable | Default | Description |
|---|---|---|
DATABASE_URL |
— | PostgreSQL connection string |
DB_USER |
gamepanel |
PostgreSQL username (Docker) |
DB_PASSWORD |
gamepanel |
PostgreSQL password (Docker) |
DB_NAME |
gamepanel |
Database name (Docker) |
DB_PORT |
5432 |
PostgreSQL exposed port |
REDIS_URL |
— | Redis connection string |
REDIS_PASSWORD |
gamepanel |
Redis password |
PORT |
3000 |
API listen port |
HOST |
0.0.0.0 |
API listen host |
NODE_ENV |
development |
Environment mode |
JWT_SECRET |
— | Required. Access token signing key |
JWT_REFRESH_SECRET |
— | Required. Refresh token signing key |
CORS_ORIGIN |
http://localhost:5173 |
Allowed CORS origin |
RATE_LIMIT_MAX |
100 |
Max requests per window |
RATE_LIMIT_WINDOW_MS |
60000 |
Rate limit window (ms) |
WEB_PORT |
80 |
Web nginx exposed port |
API_PORT |
3000 |
API exposed port (Docker) |
DAEMON_CONFIG |
/etc/gamepanel/config.yml |
Daemon config file path |
DAEMON_GRPC_PORT |
50051 |
Daemon gRPC exposed port |