Skip to content

Support Docker Desktop on Windows (UDP port forwarding broken) #18

@KevinTCoughlin

Description

@KevinTCoughlin

Problem

The server container builds and starts successfully on Docker Desktop for Windows (WSL2 backend), but clients cannot connect. The game server responds to low-level UDP ping (0xFF 0xFF 0xFF 0xFF 0x69) but not to any GoldSrc game queries (getchallenge, A2S_INFO, details).

This was confirmed to also affect the pre-built artkirienko/rehlds image — it's a Docker Desktop for Windows limitation, not specific to our image. Docker Desktop's UDP port forwarding between the Windows host and the Linux VM does not reliably deliver game traffic to the container.

Additional issues found on Docker Desktop

Issue Root cause Workaround applied
_stat on file server.cfg failed :ro,Z bind mount — :Z is a Podman SELinux flag, Docker ignores it but :ro prevents itzg helper writes Remove bind mounts (configs baked into image)
sysctls error on start net.core.rmem_max sysctl not available in Docker Desktop VM Comment out sysctls block
cap_drop: ALL failure Overly restrictive for Docker Desktop networking Comment out cap_drop + security_opt
Hang at Calling BreakpadMiniDumpSystemInit steamclient.so makes blocking IPC calls that never return Add -nomaster -insecure flags
steamclient.so: cannot open shared object file Missing Steam SDK symlink Add mkdir -p ~/.steam/sdk32 && ln -s in Containerfile

Proposed solution

Add a compose.windows.yml override (or document a WSL2-native workflow) that addresses all Docker Desktop quirks:

Option A: WSL2-native (recommended)

Run the container directly inside a WSL2 distro using Podman or Docker CE (not Docker Desktop). This uses native Linux networking with no UDP forwarding issues.

# Inside WSL2 (e.g. Ubuntu)
sudo apt install podman
cd /mnt/c/Users/excel/cs-server
podman compose up --build -d

Clients connect to the WSL2 IP (ip addr show eth0 inside WSL) from the Windows host.

Option B: compose.windows.yml override

# compose.windows.yml — Docker Desktop for Windows overrides
services:
  cstrike:
    tty: true
    stdin_open: true
    entrypoint: []
    command: >-
      bash -c "cd /hlds && export LD_LIBRARY_PATH=. &&
      exec ./hlds_run -game cstrike -bots -norestart
      +map scoutzknivez +maxplayers 20 +port 27015
      +ip 0.0.0.0 +sv_lan 1 -nomaster -insecure
      +sys_ticrate 1000 +exec server.cfg +bot_quota 10"
    # Podman-specific features not available on Docker Desktop
    # sysctls: (removed)
    # cap_drop: (removed)
    # security_opt: (removed)
    # volumes :ro,Z mounts: (removed — configs baked in)

Usage: docker compose -f compose.yml -f compose.windows.yml up -d

Option C: Containerfile changes

  • Add Steam SDK symlink in runtime stage:
    RUN mkdir -p /home/hlds/.steam/sdk32 && \
        ln -s /hlds/steamclient.so /home/hlds/.steam/sdk32/steamclient.so && \
        chown -R hlds:hlds /home/hlds

Tasks

  • Revert compose.yml and entrypoint.sh to working Podman/Linux state
  • Create compose.windows.yml override with Docker Desktop workarounds
  • Add Steam SDK symlink to Containerfile (benefits all platforms)
  • Add -nomaster -insecure as env-var toggleable flags in entrypoint.sh
  • Document WSL2-native workflow in README
  • Test client connection from Windows host → WSL2 container

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions