Skip to content

Containerization

Most game server Hosting Providers run your server inside a container. Understanding what this means and designing your server to work well inside one will save you from a category of deployment issues that are painful to debug after launch.

A container is an isolated environment that packages your server executable with its dependencies. Think of it as a lightweight, reproducible box that contains everything your server needs to run, and nothing else.

Hosting Providers use containers (typically Docker) because they provide:

  • Isolation: Each game server runs in its own environment. One server crashing or misbehaving cannot affect others on the same machine.
  • Reproducibility: The same container produces the same behavior on every machine. No “works on my machine” deployment issues.
  • Density: Containers have far less overhead than virtual machines, so more servers fit on each physical machine.
  • Fast deployment: Starting a containerized server takes seconds, not minutes.

Your server does not need to know it’s running inside a container. But it does need to avoid patterns that conflict with how containers work.

No GUI dependencies

Your server must not attempt to open windows, initialize a display, or load GUI frameworks. Containers run without a display server. If your server silently depends on X11, Wayland, or any windowing system, it will fail.

See Building Your Server Executable for headless build guidance.

No hardcoded paths

Containers map directories from the host machine into the container at runtime. Your server should not assume it lives at a specific absolute path. Use relative paths or accept the working directory via a startup argument.

Bad: /home/gameserver/MyGame/config/server.json

Good: ./config/server.json or --config /path/to/server.json

Respect environment variables

Containers commonly inject configuration through environment variables. Your server should read relevant settings from ENV vars when present, but respect runtime overrides. See Networking and Ports for more on when ENV vars make sense.

Don’t bind to localhost

Inside a container, 127.0.0.1 refers to the container’s own loopback, not the host machine. Bind your server to 0.0.0.0 (or a specified IP/interface) so it accepts connections from outside the container. This is one of the most common deployment failures.

Containers have their own filesystem. Hosting Providers mount specific directories from the host into the container so that data persists across restarts.

Your server needs to clearly separate:

  • Read-only files: Your executable, default configs, base assets. These come from your distribution and should not be modified at runtime.
  • Writable files: World saves, player data, logs, modified configs. These must be in a predictable, configurable location.

A common directory layout:

  • Directoryserver/
    • executable Read-only: your server binary
    • Directoryconfig/ Writable: server configuration
    • Directoryworlds/ Writable: world/save data
    • Directorylogs/ Writable: log files
    • Directorymods/ Writable: installed mods

Hosting Providers mount the writable directories as persistent volumes. If your server writes data outside these known locations, that data will be lost when the container restarts.

Containers use port mapping to expose your server’s ports to the outside network. Your server listens on a port inside the container, and the hosting platform maps that to a different port on the host machine.

This means:

  • Your server’s internal port and external port are often different
  • You must not hardcode port numbers
  • You must accept the port via a startup argument or environment variable
  • Binding to 0.0.0.0 (or a specified IP/interface) is mandatory (not 127.0.0.1, not localhost)

See Networking and Ports for detailed guidance.

Your server runs inside the container’s operating system, which may not have the same libraries as your development machine.

Common dependencies to verify:

  • C/C++ runtime libraries: libstdc++, libgcc_s, libc6
  • Threading libraries: libpthread
  • SSL/TLS: libssl, libcrypto (if your server makes HTTPS calls)
  • Compression: zlib, liblz4 (if your server handles compressed data)
  • .NET Runtime: If your server is a C# application
  • Mono: If using Unity’s Mono backend

Test your server on a clean, minimal Linux environment (e.g., a fresh ubuntu:22.04 Docker container) to catch missing dependencies before deployment. If it runs there, it will run in production.

If you link against specific versions of system libraries, document the minimum versions required. Hosting Providers need this information to configure their container base images.