Self-Hosting Pterodactyl with Docker Compose
What Is Pterodactyl?
Pterodactyl is an open-source game server management panel built with PHP and React. It provides a web UI for deploying, managing, and monitoring game servers — Minecraft, Terraria, Rust, CS2, Valheim, and hundreds more. Each game server runs in an isolated Docker container with resource limits, and the panel supports multiple physical nodes. It replaces paid game hosting panels like Multicraft and TCAdmin. Official site
Architecture Overview
Pterodactyl has two components:
| Component | Role | Where It Runs |
|---|---|---|
| Panel | Web UI, API, user management, server configuration | Your main server |
| Wings | Daemon that actually runs game servers in Docker containers | Each game server node |
For a single-server setup, both run on the same machine. For multi-node setups, the Panel runs centrally and Wings runs on each game server host.
Prerequisites
- A Linux server (Ubuntu 22.04+ or Debian 12 recommended)
- Docker and Docker Compose installed (guide)
- 2 GB of free RAM minimum (Panel + Wings + at least one game server)
- A domain name (required for Panel HTTPS)
- Ports open for game servers (varies by game)
Panel — Docker Compose Configuration
The Panel is the web interface and API:
services:
panel-db:
image: mariadb:11.4
container_name: pterodactyl-db
environment:
MYSQL_ROOT_PASSWORD: change-this-root-password
MYSQL_DATABASE: pterodactyl
MYSQL_USER: pterodactyl
MYSQL_PASSWORD: change-this-db-password
volumes:
- panel-db:/var/lib/mysql
networks:
- pterodactyl
restart: unless-stopped
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 5
panel-cache:
image: redis:7.4-alpine
container_name: pterodactyl-cache
volumes:
- panel-cache:/data
networks:
- pterodactyl
restart: unless-stopped
panel:
image: ghcr.io/pterodactyl/panel:v1.11.10
container_name: pterodactyl-panel
ports:
- "8080:80"
- "8443:443"
environment:
APP_URL: https://panel.example.com
APP_TIMEZONE: UTC
APP_ENV: production
# Database
DB_HOST: panel-db
DB_PORT: 3306
DB_DATABASE: pterodactyl
DB_USERNAME: pterodactyl
DB_PASSWORD: change-this-db-password
# Cache and sessions
CACHE_DRIVER: redis
SESSION_DRIVER: redis
QUEUE_DRIVER: redis
REDIS_HOST: panel-cache
# Mail (for user invitations and notifications)
MAIL_DRIVER: smtp
MAIL_HOST: smtp.example.com
MAIL_PORT: 587
MAIL_USERNAME: [email protected]
MAIL_PASSWORD: change-this-mail-password
MAIL_ENCRYPTION: tls
MAIL_FROM: [email protected]
MAIL_FROM_NAME: "Pterodactyl Panel"
volumes:
- panel-data:/app/var
- panel-logs:/app/storage/logs
- panel-nginx:/etc/nginx/http.d
networks:
- pterodactyl
depends_on:
panel-db:
condition: service_healthy
panel-cache:
condition: service_started
restart: unless-stopped
networks:
pterodactyl:
volumes:
panel-db:
panel-cache:
panel-data:
panel-logs:
panel-nginx:
Panel First-Run
# Start the panel stack
docker compose up -d
# Create the admin user
docker exec -it pterodactyl-panel php artisan p:user:make
# Follow the prompts — this creates your first admin account
Access the panel at http://your-server:8080.
Wings — Daemon Setup
Wings must be installed on each node that runs game servers. On the same machine as the Panel (single-server setup):
# Install Wings binary
curl -L -o /usr/local/bin/wings https://github.com/pterodactyl/wings/releases/latest/download/wings_linux_amd64
chmod +x /usr/local/bin/wings
Configure Wings through the Panel:
- Go to Admin → Nodes → Create New
- Set the FQDN, memory, disk, and port allocations
- Click Configuration tab and copy the generated
config.yml - Save it to
/etc/pterodactyl/config.ymlon the node - Start Wings:
wings --debug(first run) or as a systemd service
Wings systemd service
# /etc/systemd/system/wings.service
[Unit]
Description=Pterodactyl Wings Daemon
After=docker.service
Requires=docker.service
[Service]
User=root
WorkingDirectory=/etc/pterodactyl
LimitNOFILE=4096
PIDFile=/var/run/wings/daemon.pid
ExecStart=/usr/local/bin/wings
Restart=on-failure
StartLimitInterval=180
StartLimitBurst=30
RestartSec=5s
[Install]
WantedBy=multi-user.target
systemctl enable --now wings
Deploying a Game Server
Once the Panel and Wings are connected:
- Admin → Servers → Create New
- Select a nest and egg (e.g., Minecraft → Paper)
- Assign the node and port allocation
- Set resource limits (RAM, CPU, disk)
- Click Create — Wings pulls the Docker image and starts the server
| Field | What It Means |
|---|---|
| Nest | Game category (Minecraft, Rust, Source Engine, etc.) |
| Egg | Specific server type within a nest (Paper, Forge, Vanilla) |
| Allocation | IP:port combination for the game server |
| Resource limits | Max RAM, CPU %, and disk space |
Supported Games
Pterodactyl ships with eggs for 100+ games. Popular ones:
| Game | Egg | Default Port |
|---|---|---|
| Minecraft (Java) | Paper, Forge, Fabric, Vanilla | 25565 |
| Minecraft (Bedrock) | Bedrock Dedicated Server | 19132 |
| Terraria | TShock, Vanilla | 7777 |
| Rust | Oxide, Vanilla | 28015 |
| Valheim | Vanilla, Plus | 2456-2458 |
| CS2 | Counter-Strike 2 | 27015 |
| Factorio | Headless | 34197 |
| ARK: Survival | ASA, ASE | 7777 |
| Palworld | Dedicated | 8211 |
Community eggs extend support to hundreds more games via the Pterodactyl Eggs repository.
User Management
Pterodactyl supports multiple users with fine-grained permissions:
- Admin — full Panel access, can create servers and manage nodes
- Subuser — per-server permissions: console, files, databases, schedules, backups
- Server owner — assigned when the server is created
This makes Pterodactyl ideal for shared hosting or communities where different people manage different game servers.
Reverse Proxy
Behind Nginx Proxy Manager:
Proxy Host: panel.example.com → http://pterodactyl-panel:80
Enable: WebSocket Support (required for console), Force SSL
Wings communicates with the Panel over HTTPS. Ensure your SSL certificate covers the Panel domain.
Backup
| Component | Data | Priority |
|---|---|---|
| Panel database | Users, servers, nodes, allocations | Critical |
| Panel volumes | Configuration, logs | Important |
| Game server data | World saves, configs, plugins | Critical (on Wings node) |
# Panel database
docker exec pterodactyl-db mariadb-dump -u pterodactyl -p'change-this-db-password' pterodactyl > panel-backup-$(date +%Y%m%d).sql
# Game server data (on Wings node)
# Server data is in /var/lib/pterodactyl/volumes/<server-uuid>/
Pterodactyl also has built-in backup support — users can create and restore backups from the web UI.
Troubleshooting
Wings not connecting to Panel
Symptom: Node shows as offline in the Panel.
Fix: Verify config.yml has the correct Panel URL and token. Check that Wings can reach the Panel: curl https://panel.example.com. Ensure port 8080 (or 443) is open between the node and Panel.
Game server won’t start
Symptom: Server stuck at “Installing” or immediately crashes.
Fix: Check the server console in the Panel for error output. Common causes: insufficient RAM allocation (Minecraft needs at least 1 GB), missing port allocation, or Docker pull failure. Check Wings logs: journalctl -u wings -f.
File manager upload fails
Symptom: Uploading files through the Panel’s file manager errors out. Fix: Check nginx upload size limits. The Panel’s built-in file manager has a default limit. For large files (mods, world saves), use SFTP instead — SFTP credentials are shown in the Panel under each server’s Settings tab.
High CPU usage from a game server
Symptom: One game server consuming all CPU, affecting others.
Fix: Set CPU limits in the server’s Build Configuration. Use 0 for unlimited or a percentage (e.g., 200 for 2 cores). Docker enforces these limits via cgroups.
Resource Requirements
- Panel: ~300 MB RAM (Panel + MariaDB + Redis)
- Wings daemon: ~50 MB RAM
- Per game server: Varies widely — Minecraft: 1-4 GB, Terraria: 256 MB, Rust: 4-8 GB
- Disk: 1 GB for Panel, game servers vary (Minecraft world: 1-10 GB typical)
Verdict
Pterodactyl is the gold standard for self-hosted game server management. The Docker isolation means game servers can’t interfere with each other, resource limits prevent runaway processes, and the web UI makes management accessible to non-sysadmins. For simpler setups (single game, single server), you might prefer running a bare Docker container directly. But the moment you manage 2+ game servers or share access with friends, Pterodactyl’s panel is worth the setup time. Pelican is the actively-maintained fork — check it if Pterodactyl’s development slows.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments