[GH-ISSUE #257] Feature Request: Allow configuration of docker container hostname and name #176

Open
opened 2026-10-15 12:57:43 +00:00 by bsakaguchi · 2 comments
Owner

Originally created by @Nurgus on GitHub (Sep 24, 2025).
Original GitHub issue: https://github.com/games-on-whales/wolf/issues/257

At the moment the app containers use docker containerid as a hostname and Wolf_xxxx as the container name and the same xxx as the default app_state_folder.. It'd be super nice if we could configure both in the config. We can set the storage via app_state_folder, be nice to have one variable substring of all 3 for each user.

The container's internal hostname appears when using steam link and steam's remote streaming, which is sometimes handy. At the moment it looks like this:

Image

I know I can do all this manually for each user but it'd be nice to automate it.

Originally created by @Nurgus on GitHub (Sep 24, 2025). Original GitHub issue: https://github.com/games-on-whales/wolf/issues/257 At the moment the app containers use docker containerid as a hostname and Wolf<appname>_xxxx as the container name and the same xxx as the default app_state_folder.. It'd be super nice if we could configure both in the config. We can set the storage via app_state_folder, be nice to have one variable substring of all 3 for each user. The container's internal hostname appears when using steam link and steam's remote streaming, which is sometimes handy. At the moment it looks like this: <img width="557" height="373" alt="Image" src="https://github.com/user-attachments/assets/a54d1e79-aef4-4824-b51f-a176b8cfd292" /> I know I can do all this manually for each user but it'd be nice to automate it.
Author
Owner

@ABeltramo commented on GitHub (Sep 24, 2025):

This will be possible once https://github.com/games-on-whales/wolf/pull/179 will be finally finished and merged. We have proper users and lobbies support; the hostname can be something meaningful then..

<!-- gh-comment-id:3330496951 --> @ABeltramo commented on GitHub (Sep 24, 2025): This will be possible once https://github.com/games-on-whales/wolf/pull/179 will be finally finished and merged. We have proper users and lobbies support; the hostname can be something meaningful then..
Author
Owner

@jeanpdoliveira commented on GitHub (Sep 9, 2026):

Adding a data point from a different angle than the Steam Link display name: the container hostname is not only cosmetic today, and it also leaks into the persistent Proton/Wine prefix, where it changes on every session.

Where it comes from

Wolf creates a new container per Moonlight session and the shipped app definitions do not set Hostname in base_create_json. Docker's documented default then applies and the container hostname is the container ID, so gethostname() inside the container returns a different value every session.

This is already configurable with no code change: DockerAPI::create (src/core/src/platforms/all/docker/docker/docker.cpp) parses base_create_json, then overwrites only Image and ExposedPorts, merges Env, and merges Binds/Devices plus sets PortBindings inside HostConfig. A top-level Hostname reaches the Docker API untouched.

Where it ends up

A new container means a new wineserver. When ntdll builds the parameters for the first Windows process in the prefix (build_initial_params -> run_wineboot, dlls/ntdll/unix/env.c) it tries to create \KernelObjects\__wineboot_event; in a fresh wineserver that event does not exist yet, so it runs wineboot.exe --init.

wineboot then calls create_computer_name_keys() unconditionally from main() (programs/wineboot/wineboot.c), before the init || update gate. It reads gethostname() and calls SetComputerNameExA, which writes into the prefix registry:

  • HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Hostname (persistent)
  • HKLM\System\CurrentControlSet\Control\ComputerName\ComputerName (persistent, uppercased and truncated to 15 chars)
  • HKLM\System\CurrentControlSet\Control\ComputerName\ActiveComputerName (volatile, repopulated on every boot from the persistent one), which is what GetComputerNameW() reads back

Net effect: the prefix under app_state_folder persists, but the Windows machine name recorded inside it is re-derived from an ephemeral container hostname on every stream.

Measured

Same prefix (compatdata/1874000, created 2026-09-05), before and after adding Hostname to base_create_json:

# before, session running as container 4c5d119d9890:
[System\ControlSet001\Control\ComputerName\ComputerName] 1788912295
"ComputerName"="4C5D119D9890"

# after, one session with Hostname set:
[System\ControlSet001\Control\ComputerName\ComputerName] 1788988569
"ComputerName"="WOLFSTEAM"
"Hostname"="WOLFSTEAM"       # Tcpip\Parameters

# a second, different container (new session) left the file byte-identical:
md5 system.reg unchanged, key timestamp unchanged

The prefix was created on 09-05 but the key carries a 09-09 timestamp, so this is a rewrite on a later run, not a value set once at prefix creation. Across the 15 Proton prefixes in my app_state_folder, that key held 12 distinct values before the change, all in Docker short-ID form. Same host, same install, same user account.

For contrast, Valve already treats prefix machine identity as worth preserving: the proton script carries HKLM\Software\Microsoft\Cryptography\MachineGuid across prefix rebuilds (old_machine_guid, proton_9.0 lines 587 and 847-850). ComputerName is the one identifier it cannot stabilise, because Wine re-derives it from the kernel hostname instead of storing it.

Why this matters beyond the display name

Any Windows software inside the prefix that folds GetComputerNameW() into a machine fingerprint sees a brand new machine on every session, even though nothing on the host changed. Licensing implementations are the visible case: #248 has two users reporting activation lockouts of the "installed on too many machines" kind (2025-09-05 and 2025-11-26), both attributing it to switching Proton versions. I hit the same class of lockout on a legitimately owned title after 9 sessions in one day, with no Proton version change involved (single config_info, no per-app CompatToolMapping).

Being explicit about the evidence boundary:

  • Established: the hostname is per container, wineboot rewrites the prefix keys from it on every run, my prefixes held 12 distinct values, and setting Hostname stops the churn.
  • Not established: that this is what triggered the lockout. Treat that as a plausible consequence, not a demonstrated cause.

One constraint on the shape of the fix

A single global constant would be the wrong answer. src/moonlight-server/audio/pulse_router.cpp keys its routing map on the container hostname (host_to_session.set(ev.hostname, ev.session_id)). Two concurrent containers sharing one hostname would collide there and the second would overwrite the first mapping.

What satisfies both is a hostname stable across sessions of the same profile and unique across concurrent profiles, for example derived from the profile id. That matches the "something meaningful" @ABeltramo described once users and lobbies existed, and it would give the audio router a key that no longer depends on a value Docker randomises per container.

As a local workaround for a single-session setup, a fixed value in base_create_json works today, keeping it to 15 characters or fewer since the NetBIOS name is truncated there:

base_create_json = '''{
  "Hostname": "wolf-steam",
  "HostConfig": { "IpcMode": "host", "Privileged": false }
}'''

Happy to send a docs PR describing the current behaviour and this constraint.

<!-- gh-comment-id:5609580620 --> @jeanpdoliveira commented on GitHub (Sep 9, 2026): Adding a data point from a different angle than the Steam Link display name: the container hostname is not only cosmetic today, and it also leaks into the *persistent* Proton/Wine prefix, where it changes on every session. ### Where it comes from Wolf creates a new container per Moonlight session and the shipped app definitions do not set `Hostname` in `base_create_json`. Docker's documented default then applies and the container hostname is the container ID, so `gethostname()` inside the container returns a different value every session. This is already configurable with no code change: `DockerAPI::create` (`src/core/src/platforms/all/docker/docker/docker.cpp`) parses `base_create_json`, then overwrites only `Image` and `ExposedPorts`, merges `Env`, and merges `Binds`/`Devices` plus sets `PortBindings` inside `HostConfig`. A top-level `Hostname` reaches the Docker API untouched. ### Where it ends up A new container means a new wineserver. When ntdll builds the parameters for the first Windows process in the prefix (`build_initial_params` -> `run_wineboot`, `dlls/ntdll/unix/env.c`) it tries to create `\KernelObjects\__wineboot_event`; in a fresh wineserver that event does not exist yet, so it runs `wineboot.exe --init`. `wineboot` then calls `create_computer_name_keys()` unconditionally from `main()` (`programs/wineboot/wineboot.c`), before the `init || update` gate. It reads `gethostname()` and calls `SetComputerNameExA`, which writes into the prefix registry: * `HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Hostname` (persistent) * `HKLM\System\CurrentControlSet\Control\ComputerName\ComputerName` (persistent, uppercased and truncated to 15 chars) * `HKLM\System\CurrentControlSet\Control\ComputerName\ActiveComputerName` (volatile, repopulated on every boot from the persistent one), which is what `GetComputerNameW()` reads back Net effect: the prefix under `app_state_folder` persists, but the Windows machine name recorded inside it is re-derived from an ephemeral container hostname on every stream. ### Measured Same prefix (`compatdata/1874000`, created 2026-09-05), before and after adding `Hostname` to `base_create_json`: ``` # before, session running as container 4c5d119d9890: [System\ControlSet001\Control\ComputerName\ComputerName] 1788912295 "ComputerName"="4C5D119D9890" # after, one session with Hostname set: [System\ControlSet001\Control\ComputerName\ComputerName] 1788988569 "ComputerName"="WOLFSTEAM" "Hostname"="WOLFSTEAM" # Tcpip\Parameters # a second, different container (new session) left the file byte-identical: md5 system.reg unchanged, key timestamp unchanged ``` The prefix was created on 09-05 but the key carries a 09-09 timestamp, so this is a rewrite on a later run, not a value set once at prefix creation. Across the 15 Proton prefixes in my `app_state_folder`, that key held 12 distinct values before the change, all in Docker short-ID form. Same host, same install, same user account. For contrast, Valve already treats prefix machine identity as worth preserving: the `proton` script carries `HKLM\Software\Microsoft\Cryptography\MachineGuid` across prefix rebuilds (`old_machine_guid`, proton_9.0 lines 587 and 847-850). ComputerName is the one identifier it cannot stabilise, because Wine re-derives it from the kernel hostname instead of storing it. ### Why this matters beyond the display name Any Windows software inside the prefix that folds `GetComputerNameW()` into a machine fingerprint sees a brand new machine on every session, even though nothing on the host changed. Licensing implementations are the visible case: #248 has two users reporting activation lockouts of the "installed on too many machines" kind (2025-09-05 and 2025-11-26), both attributing it to switching Proton versions. I hit the same class of lockout on a legitimately owned title after 9 sessions in one day, with no Proton version change involved (single `config_info`, no per-app `CompatToolMapping`). Being explicit about the evidence boundary: * **Established**: the hostname is per container, `wineboot` rewrites the prefix keys from it on every run, my prefixes held 12 distinct values, and setting `Hostname` stops the churn. * **Not established**: that this is what triggered the lockout. Treat that as a plausible consequence, not a demonstrated cause. ### One constraint on the shape of the fix A single global constant would be the wrong answer. `src/moonlight-server/audio/pulse_router.cpp` keys its routing map on the container hostname (`host_to_session.set(ev.hostname, ev.session_id)`). Two concurrent containers sharing one hostname would collide there and the second would overwrite the first mapping. What satisfies both is a hostname stable across sessions of the same profile and unique across concurrent profiles, for example derived from the profile id. That matches the "something meaningful" @ABeltramo described once users and lobbies existed, and it would give the audio router a key that no longer depends on a value Docker randomises per container. As a local workaround for a single-session setup, a fixed value in `base_create_json` works today, keeping it to 15 characters or fewer since the NetBIOS name is truncated there: ```toml base_create_json = '''{ "Hostname": "wolf-steam", "HostConfig": { "IpcMode": "host", "Privileged": false } }''' ``` Happy to send a docs PR describing the current behaviour and this constraint.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
games-on-whales/wolf#176
No description provided.