Skip to main content

Docker for Game Servers

Historically, game servers were installed directly on the host operating system. This led to "dependency hell" (Server A needs Java 8, Server B needs Java 17) and made migrating servers difficult.

Docker solves this by packaging the application (the game server) and all its dependencies (Java, PHP binaries, libraries) into a standardized unit called a container.

Why Docker?

  1. Isolation: Each container runs in its own isolated environment (using namespaces and cgroups). A memory leak in a Hub server container will not crash the Factions server container.
  2. Consistency: A Docker container behaves exactly the same way on your local development laptop as it does on the production server.
  3. Rapid Deployment: Spinning up a new server instance is as simple as running a single command.
  4. Resource Limits: Docker makes it incredibly easy to limit CPU and RAM usage per instance.

Basic Docker Concepts

  • Image: A read-only template with instructions for creating a Docker container. (e.g., An image containing Ubuntu, PMMP, and PHP).
  • Container: A runnable instance of an image.
  • Volume: A mechanism for persisting data generated by and used by Docker containers. Without a volume, when a container is deleted, all its data (like the game world) is lost.

Example: Running PocketMine-MP in Docker

While you can build your own images using a Dockerfile, many community images already exist.

To run a basic PMMP server using a hypothetical community image:

docker run -d \
--name pmmp-hub \
-p 19132:19132/udp \
-v /path/to/my/server/data:/data \
-m 2G \
--cpus 1 \
pmmp/pocketmine-mp:latest

Explanation of arguments:

  • -d: Run in detached mode (in the background).
  • --name: Give the container a recognizable name.
  • -p: Port mapping (HostPort:ContainerPort). Maps the host's UDP port 19132 to the container's UDP port 19132.
  • -v: Volume mapping (HostPath:ContainerPath). This is critical. It mounts a directory on your host machine to /data inside the container. This ensures your worlds and plugins are saved even if the container is destroyed.
  • -m: Limits the container to 2 Gigabytes of RAM.
  • --cpus: Limits the container to a maximum of 1 CPU core.

Docker Compose

For a network, you often want to start multiple containers together (e.g., Waterdog proxy + Hub + Factions). Docker Compose allows you to define this in a single docker-compose.yml file.

version: '3'
services:
waterdog:
image: waterdog/proxy:latest
ports:
- "19132:19132/udp"
volumes:
- ./waterdog-data:/data
networks:
- gamenet

hub:
image: pmmp/pocketmine-mp:latest
volumes:
- ./hub-data:/data
networks:
- gamenet

networks:
gamenet:
driver: bridge

Notice in this Compose file, only Waterdog exposes a port to the host. The hub server only communicates internally over the gamenet Docker network, increasing security.