Building a Secure Game Server Infrastructure
I designed and deployed a a game server hosting environment using virtualization, containerization, and secure tunnel routing. The goal was to host multiple multiplayer game servers (Minecraft and Enshrouded) without exposing any public ports on my home network while maintaining full control over infrastructure.
This guide walks through the entire process, from setting up the hypervisor to debugging network issues, and is designed for learners who want to understand how to build similar infrastructure in their own homelab.
What You'll Learn#
By the end of this guide, you'll understand:
- How to set up and manage virtual machines using Proxmox VE
- How to containerize game servers with Docker and Docker Compose
- How to secure external access using reverse tunnels (Playit.gg)
- How to configure DNS for custom domain routing
- How to debug networking issues and validate port exposure
- How to migrate services between virtual machines
- How to manage persistent data and backups
Project Context: A Migration Journey#
This project began with a single game service running on an existing VM. As the infrastructure grew and requirements changed, I decided to migrate all services to a dedicated VM (gameserv-vm) to improve organization, resource allocation, and maintainability.
The Migration Path:
- Starting Point: Services running on media-serv (Minecraft, Docker, Portainer, and Playit tunnel agent)
- Goal: Migrate everything to a new, dedicated gameserv-vm without data loss or downtime
- Outcome: Successful migration with improved architecture and zero data loss
While this guide is structured to show the final architecture and best practices, Phase 7 details the actual migration process. The phases describe both the initial deployment concepts and the refined setup on gameserv-vm.
This guide presents the final architecture first (Phases 1-6) to help you understand how everything works together, then covers the migration process (Phase 7) as a real-world example of service migration between VMs. Whether you're building fresh or migrating existing services, both approaches are covered.
๐ท๏ธ Skills & Technologies#
This project demonstrates hands-on experience with the following technologies and tools:
๐งฉ Virtualization & Infrastructure#
๐ณ Containers & DevOps#
๐ Networking & DNS#
๐งฐ Tools & Commands#
๐ฎ Game Servers#
Project Architecture Overview#
Before diving into implementation, let's understand the overall architecture:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Proxmox VE โ
โ (Hypervisor running on hardware) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Virtual Network Bridge
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ gameserv-vm โ
โ Debian-based Linux Server โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Docker: โ โ Docker: โ โ
โ โ Enshrouded โ โ Minecraft โ โ
โ โ Server โ โ Paper/Purpur โ โ
โ โโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Playit Tunnel Agent โ โ
โ โ - Handles all inbound game traffic โ โ
โ โ - No public ports exposed on VM or Proxmox โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Docker: Portainer CE โ โ
โ โ - Manage stacks, volumes, logs โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ Encrypted Tunnel Connections
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Playit.gg Cloud โ
โ - Custom domain integration โ
โ - Automatically handles NAT โ
โ - Creates public TCP/UDP links โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Players / Clients โ
โ - Connect via custom domain โ
โ - No knowledge of internal IPs โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Key Components:
- Proxmox VE: Hypervisor managing virtual machines
- Linux VMs: Debian-based servers hosting all services
- Docker Containers: Isolated game server environments
- Playit.gg Tunnel Agent: Securely routes traffic without port forwarding
- Porkbun DNS: Maps custom domains to tunnel endpoints
- Portainer: Web-based Docker management interface
This design provides security by defaultโno inbound firewall rules, no port forwarding, no exposed attack surface. The tunnel service handles NAT traversal automatically while you maintain full control over the infrastructure.
Phase 1: Proxmox Hypervisor Setup#
What is Proxmox?#
Proxmox Virtual Environment (PVE) is an open-source virtualization platform that combines KVM (Kernel-based Virtual Machine) for full virtualization and LXC for lightweight containers. It provides enterprise-grade features through a web-based management interface.
Virtual Machine Architecture#
For this project, I worked with multiple VMs in a migration scenario:
- media-serv โ Original VM where services initially ran
- gameserv-vm โ New dedicated VM created specifically for hosting game servers (migration target)
The decision to create a dedicated gameserv-vm came from the need to:
- Isolate game server workloads from other services
- Allocate resources specifically optimized for game hosting
- Improve maintainability and future scalability
- Practice infrastructure migration in a controlled environment
VM Configuration Tasks#
Creating the Game Server VM:
- Allocated appropriate resources (8 CPU cores, 16GB RAM)
- Created virtual disk with 100GB storage
- Configured virtual network bridge for Docker networking
- Installed Debian-based Linux server
Resource Planning Considerations:
- Game servers are CPU-intensive during world generation
- Minecraft requires sustained memory allocation (no swapping)
- Enshrouded requires more CPU and memory resource allocation than Minecraft to operate
- Storage I/O matters for chunk loading performance
Start with baseline resources and monitor performance. Proxmox makes it easy to resize VMs, but you'll need to restart the VM for CPU/RAM changes. Storage can typically be expanded online.
Phase 2: Linux Server Administration#
Once the VM was running, I needed to configure the Debian-based Linux environment. This involved fundamental system administration tasks that every infrastructure engineer should understand.
Essential Linux Tasks Performed#
File System Management:
- Removing protected configuration files with
chmodandchown - Editing configuration files using
nano - Understanding file permissions and ownership
Service Management:
- Managing services with
systemctl(start, stop, enable, status) - Reviewing system logs using
journalctl - Configuring services to auto-start on boot
Debugging Techniques:
- Analyzing service crashes through logs
- Identifying port conflicts
- Resolving permission issues
If you're new to Linux administration, focus on these foundational skills first:
- Navigating the filesystem (
cd,ls,pwd) - Editing files (
nano,vim) - Managing permissions (
chmod,chown) - Viewing logs (
journalctl,tail -f) - Managing services (
systemctl)
Key Commands Used#
# Check service status
systemctl status docker
# View live service logs
journalctl -u docker -f
# Fix file permissions
sudo chown -R user:user /path/to/directory
# Check disk space
df -h
# Monitor system resources
htopPhase 3: Docker and Containerization#
Why Docker for Game Servers?#
Docker provides several advantages for game server hosting:
- Isolation: Each server runs in its own container with dedicated resources
- Reproducibility: Configuration is defined in code (
docker-compose.yml) - Portability: Easy migration between VMs or physical hosts
- Version Control: Roll back to previous configurations easily
- Resource Management: Control CPU, memory, and network limits per container
Containerized Services#
I deployed these containers on the gameserv-vm:
- Enshrouded Dedicated Server โ Survival game server
- Minecraft Paper/Purpur Server โ Optimized Minecraft server
- Playit.gg Tunnel Agent โ Secure tunnel for external access
- Portainer CE โ Docker management GUI
Docker Compose Configuration#
Here's a simplified example of the Minecraft server configuration:
version: '3.8'
services:
minecraft:
image: itzg/minecraft-server:latest
container_name: minecraft-server
restart: unless-stopped
environment:
EULA: "TRUE"
TYPE: "PAPER"
VERSION: "1.20.4"
MEMORY: "6G"
DIFFICULTY: "normal"
OPS: "your_username"
WHITELIST: "player1,player2"
ports:
- "25565:25565"
volumes:
- ./minecraft-data:/data
networks:
- game_network
networks:
game_network:
driver: bridgeDocker Tasks and Lessons Learned#
Configuration Management:
- Creating and validating
docker-compose.ymlfiles - Understanding environment variables and their impact
- Mapping persistent paths with bind mounts vs. volumes
Volume Management:
- Managing Docker volumes for persistent data storage
- Backing up and restoring volume data through Portainer
- Safely removing corrupted configuration files
- Understanding the difference between bind mounts and named volumes
Container Lifecycle:
- Starting, stopping, and restarting containers
- Reading container logs for debugging (
docker logs -f container_name) - Rebuilding containers after configuration changes
- Accessing container shells for troubleshooting (
docker exec -it container_name bash)
By default, data inside containers is ephemeralโit disappears when the container is removed. Always use volumes or bind mounts for game save data, world files, and configuration. Otherwise, you'll lose player progress when updating containers.
Using Portainer for Management#
Portainer CE provides a web-based GUI for Docker management, which is especially helpful for:
- Visualizing container status and resource usage
- Browsing volume contents and downloading backups
- Viewing real-time logs without SSH access
- Managing multiple Docker hosts from one interface
- Quick container restarts and rebuilds
Phase 4: Networking and Tunnel Architecture#
This phase involved extensive network troubleshooting and validation. A critical skill for any infrastructure project.
Understanding Port Requirements#
Different game servers have different networking requirements:
Minecraft:
- TCP 25565 โ Main game connection
- Supports both Java and Bedrock (with plugins)
Enshrouded:
- UDP queryPort โ Single port for game queries and connections
- Modern builds simplified from older multi-port requirements
Network Debugging Process#
Step 1: Identify Active Ports
# Check what ports are listening
ss -tulnp
# Example output:
# tcp LISTEN 0 128 *:25565 *:* users:(("java",pid=1234))
# udp LISTEN 0 0 *:15636 *:* users:(("enshrouded",pid=5678))Step 2: Validate Port Accessibility
# Test local connectivity
nc -vz localhost 25565
# Test from another machine on the network
nc -vz 192.168.1.100 25565Step 3: Verify Tunnel Routing
- Access Playit.gg dashboard to confirm tunnel status
- Test external connectivity using public endpoint
- Check tunnel agent logs for connection issues
Playit.gg Tunnel Configuration#
Why Playit.gg?
Traditional port forwarding exposes your home IP address and requires router configuration. Playit.gg provides:
- No port forwarding required โ Works behind NAT and restrictive firewalls
- DDoS protection โ Traffic is filtered before reaching your server
- Custom domains โ Map your own DNS names to tunnel endpoints
- Zero-trust security โ No inbound firewall rules needed
Tunnel Setup Process:
- Run Playit agent as a Docker container
- Authenticate and claim the agent in the web dashboard
- Create tunnel mappings for each game server port
- Configure tunnel to auto-start on system boot
- Link custom domain names (covered in next section)
Tunnel Agent Docker Compose:
version: '3.8'
services:
playit:
image: playit/playit:latest
container_name: playit-agent
restart: unless-stopped
volumes:
- ./playit-data:/root/.playit
network_mode: hostI initially ran separate tunnel agents for each service, which was unnecessary and harder to manage. Consolidate into a single tunnel agent with multiple port mappingsโit's simpler, uses fewer resources, and easier to maintain.
Key Networking Lessons#
Port Discovery:
- Modern Enshrouded uses only one UDP port, not the multiple ports from early releases
- Removed obsolete tunnel mappings to reduce complexity
- Validated actual port usage before configuring tunnels
Network Validation Tools:
ss -tulnpโ Shows listening ports and associated processesnc -vzโ Tests TCP/UDP connectivity- External port checkers โ Verify public accessibility
- Playit.gg dashboard โ Confirm tunnel health and traffic
Phase 5: DNS Configuration with Porkbun#
DNS (Domain Name System) maps human-readable domain names to IP addresses (or in this case, tunnel endpoints). This allows players to connect using game.yourdomain.com instead of remembering IP addresses and ports.
What is Porkbun?
Porkbunโ is a domain registrar and DNS hosting provider known for its transparent pricing and user-friendly interface. Unlike traditional registrars with hidden fees, Porkbun includes free WHOIS privacy, SSL certificates, and straightforward DNS managementโmaking it an excellent choice for homelab projects and small-scale infrastructure.
DNS Records Created#
I configured the following DNS records in Porkbun:
Example Records:
Type Name Value TTL
A minecraft playit-endpoint-ip 600
CNAME enshrouded minecraft.yourdomain.com 600
DNS Configuration Tasks#
Record Management:
- Created A records pointing to Playit tunnel endpoints
- Used CNAME records for service aliases
- Removed outdated wildcard records from previous configurations
- Set appropriate TTL (Time To Live) values for flexibility
Troubleshooting DNS:
- Resolved nameserver warnings in Porkbun dashboard
- Validated DNS propagation using
digcommand - Re-linked domains after VM migration to new tunnel endpoints
DNS Validation:
# Check DNS resolution
dig minecraft.yourdomain.com
# Expected output shows A record pointing to tunnel IP
# minecraft.yourdomain.com. 600 IN A 123.456.789.10DNS changes can take up to 24-48 hours to propagate globally, but most updates appear within minutes. Use a lower TTL (like 600 seconds) during active configuration, then increase it for stability once everything works.
Phase 6: Game Server Deployments#
Minecraft Server (Paper/Purpur)#
Paper and Purpur are optimized Minecraft server implementations that improve performance and add additional features over vanilla Minecraft.
Deployment Tasks:
- Deployed server through Docker using
itzg/minecraft-serverimage - Managed world directories and implemented backup strategy
- Configured whitelist and operator permissions
- Set appropriate Java memory allocation (avoid swapping)
- Removed duplicated or corrupted world data
- Validated version compatibility with client
Configuration Best Practices:
environment:
MEMORY: "6G" # Allocate 75% of available RAM
TYPE: "PAPER" # Use Paper for performance
VERSION: "1.20.4" # Lock version for stability
DIFFICULTY: "normal"
MAX_PLAYERS: "20"
VIEW_DISTANCE: "10" # Balance performance vs. render distance
SIMULATION_DISTANCE: "8"Common Issues Resolved:
- Removed duplicate world directories causing conflicts
- Fixed whitelist enforcement not applying
- Resolved permission issues preventing admin commands
- Cleaned up redundant environment variables
Enshrouded Dedicated Server#
Enshrouded is a newer game with evolving server requirements. This required more troubleshooting due to changing port configurations.
Deployment Tasks:
- Rebuilt
docker-compose.ymlfrom scratch after corruption - Removed write-protected configuration files blocking startup
- Updated port mappings to reflect current game version requirements
- Validated correct queryPort behavior for newer builds
- Ensured savegame persistence in Docker volume
- Tested external reachability through tunnel
Key Learning: Game server requirements change between versions. Always:
- Check official documentation for current port requirements
- Monitor server logs during startup for configuration errors
- Validate connectivity after updates
- Keep backups before major version changes
Phase 7: Service Migration Between VMs#
One of the most valuable learning experiences was migrating services from media-serv to gameserv-vm without data loss.
Migration Process#
Pre-Migration Preparation:
- Document current configuration (compose files, environment variables, volumes)
- Backup all Docker volumes using Portainer download feature
- Export tunnel agent configuration
- Record DNS mappings and tunnel endpoints
Migration Steps:
- Stop containers on source VM (media-serv)
- Download volume data through Portainer
- Transfer data to new VM (gameserv-vm) via SCP or shared storage
- Recreate Docker Compose configurations on target VM
- Restore volume data and validate file permissions
- Start containers and verify functionality
- Update tunnel agent registration to new VM
- Test connectivity before decommissioning old VM
Validation Checklist:
- โ All game saves and world data intact
- โ Player whitelist and permissions preserved
- โ Configuration files properly migrated
- โ External connectivity through tunnels working
- โ DNS records pointing to correct endpoints
- โ Auto-start on boot configured
Never delete the source VM until you've fully validated the migration. Keep it running but stopped for at least 48 hours in case you discover missing data or configuration issues.
Phase 8: Backups and Data Management#
Backup Strategy#
Manual Backups:
- Download Docker volumes through Portainer web interface
- Store backups on separate physical storage
- Test restoration procedure before disasters happen
- Maintain retention policy (keep last 7 daily, 4 weekly backups)
Volume Management:
- Understand difference between named volumes and bind mounts
- Clean old or protected directories causing conflicts
- Verify no data loss during VM transitions
- Document volume locations and purposes
Minecraft World Backup Example:
# Stop the server (prevents world corruption)
docker stop minecraft-server
# Backup the world data
tar -czf minecraft-backup-$(date +%Y%m%d).tar.gz ./minecraft-data/world
# Restart the server
docker start minecraft-server
# Verify backup integrity
tar -tzf minecraft-backup-$(date +%Y%m%d).tar.gz | headTools and Commands Reference#
Linux Administration#
rm -rf /path/to/directory # Remove files/directories
chmod 755 /path/to/file # Change file permissions
chown user:group /path/to/file # Change ownership
systemctl enable docker # Enable service on boot
systemctl start docker # Start service
systemctl status docker # Check service status
journalctl -u docker -f # Follow service logs
nano /path/to/config # Edit configuration filesNetworking#
ss -tulnp # Show listening ports
nc -vz hostname port # Test connectivity
dig domain.com # Check DNS resolution
ip addr show # Show network interfaces
ping -c 4 hostname # Test basic connectivityDocker#
docker compose up -d # Start containers in background
docker compose down # Stop and remove containers
docker logs -f container_name # Follow container logs
docker exec -it container_name bash # Access container shell
docker volume ls # List volumes
docker volume rm volume_name # Remove volume
docker ps # Show running containers
docker stats # Show resource usageProxmox#
- VM create/delete/resize through web interface
- Virtual network bridge configuration
- Storage pool and disk management
- Console access for troubleshooting
- Snapshot management for backups
Key Takeaways and Skills Demonstrated#
Technical Skills#
Virtualization:
- Proxmox VE configuration and VM management
- Resource allocation and capacity planning
- Virtual networking and storage
Linux Administration:
- Debian-based server configuration
- Service management with systemd
- Log analysis and troubleshooting
- File permissions and ownership
Containerization:
- Docker and Docker Compose
- Volume management and data persistence
- Container networking
- Portainer administration
Networking:
- Port identification and validation
- NAT traversal using tunnels
- Network troubleshooting methodology
- DNS configuration and management
Security:
- Zero-trust architecture (no exposed ports)
- Reverse tunnel implementation
- Service isolation through containers
Soft Skills#
- Systematic troubleshooting: Following a methodical debugging process
- Documentation: Maintaining detailed records of configuration
- Planning: Preparing migration strategies with rollback plans
- Persistence: Debugging complex multi-layer issues
What's Next?#
This infrastructure provides a solid foundation for future expansion:
Potential Enhancements:
- Automated backup scripts with rotation
- Monitoring and alerting (Prometheus + Grafana)
- Additional game servers (Valheim, Terraria, etc.)
- Load balancing for high-traffic servers
- Infrastructure as Code using Terraform/Ansible
Learning Opportunities:
- Implement CI/CD for automated server updates
- Explore Kubernetes for orchestration at scale
- Add observability with centralized logging
- Set up disaster recovery procedures
Resources for Further Learning#
Proxmox:
Docker:
Linux Administration:
Networking:
The best way to learn infrastructure skills is through hands-on projects like this. Start small, document everything, don't be afraid to break things in your homelab, and always maintain backups. Every problem you solve teaches you something valuable.
Project Status: โ Complete and operational Uptime: Serving players reliably Next Challenge: Backups and modding
