Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions src/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,22 @@ RUN git clone https://github.com/quietvoid/runfromprocess-rs . \

FROM debian:${DEBIAN_VERSION}-slim AS wine-base

# As at May 2024 Wayland Native works wine 9.9 or later:
# WINE_BRANCH="devel"
# For Specific version fix add WINE_VERSION,
# make sure to add "=" to the start, comment out for latest
# WINE_VERSION="=9.9~bookworm-1"
# Wine 11: EGL is the default OpenGL backend (replaced GLX since 10.17).
# Wayland native support included since 9.9. Pinned to 11.5 devel.
# To update, change WINE_VERSION (prefix with "=", omit for latest devel)
# WINE_VERSION="=11.5~${DEBIAN_VERSION}-1"
ARG DEBIAN_VERSION
ARG WINE_BRANCH="devel"
ARG WINE_VERSION="=9.9~${DEBIAN_VERSION}-1"
ARG WINETRICKS_VERSION=20240105
ARG WINE_VERSION="=11.5~${DEBIAN_VERSION}-1"
ARG WINETRICKS_VERSION=20260125

# Install prerequisites
# - ca-certificates for wget and curl
# - curl used in zwift authentication script
# - gamemode for freedesktop screensaver inhibit
# - gosu for invoking scripts in entrypoint
# - libegl1 and libgl1 for GL library
# - libvulkan1 for vulkan loader library
# - libegl1/libgl1 and i386 variants for GL/EGL library
# - libvulkan1 and i386 variant for vulkan loader library
# - procps for pgrep
# - sudo for normal user installation
# - wget for downloading winehq key
Expand All @@ -51,8 +50,11 @@ RUN dpkg --add-architecture i386 \
gamemode \
gosu \
libegl1 \
libegl1:i386 \
libgl1 \
libgl1:i386 \
libvulkan1 \
libvulkan1:i386 \
Comment on lines +53 to +57

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you add the 32-bit libraries? They're not needed?

procps \
sudo \
wget \
Expand All @@ -75,11 +77,17 @@ RUN wget -qO /etc/apt/trusted.gpg.d/winehq.asc https://dl.winehq.org/wine-builds
&& chmod +x /usr/local/bin/winetricks

# Create passwordless user and make nvidia libraries discoverable
# Register NVIDIA as a GLVND EGL vendor so the dispatcher loads libEGL_nvidia.so.0
# when injected by the NVIDIA container runtime. Harmless if NVIDIA is absent
# (GLVND silently skips vendors whose library is not found).
RUN adduser --disabled-password --gecos '' user \
&& adduser user sudo \
&& echo '%SUDO ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
&& echo "/usr/local/nvidia/lib" >> /etc/ld.so.conf.d/nvidia.conf \
&& echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf
&& echo "/usr/local/nvidia/lib64" >> /etc/ld.so.conf.d/nvidia.conf \
&& mkdir -p /usr/share/glvnd/egl_vendor.d \
&& printf '{"file_format_version":"1.0.0","ICD":{"library_path":"libEGL_nvidia.so.0"}}\n' \
> /usr/share/glvnd/egl_vendor.d/10_nvidia.json
Comment on lines +88 to +90

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you need to add the 10_nvidia.json file? It already exists in the container for me (tried with both docker and podman), I'm guessing this is something the nvidia container toolkit does.

user@glenn-main-pc:/$ ls /usr/share/glvnd/egl_vendor.d/
10_nvidia.json  50_mesa.json
user@glenn-main-pc:/$ cat /usr/share/glvnd/egl_vendor.d/10_nvidia.json 
{
    "file_format_version" : "1.0.0",
    "ICD" : {
        "library_path" : "libEGL_nvidia.so.0"
    }
}


# Required for non-glvnd setups
ENV LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/i386-linux-gnu:/usr/local/nvidia/lib:/usr/local/nvidia/lib64
Expand Down
22 changes: 20 additions & 2 deletions src/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ if [[ ${CONTAINER_TOOL} == "docker" ]]; then
# This avoids a costly recursive find on every normal startup
local target="${1:?}"
local result
[[ -d ${target} ]] && result="$(find "${target}" -maxdepth 0 \( ! -user user -o ! -group user \) -print 2> /dev/null)" && [[ -n ${result} ]]
[[ -d ${target} ]] && result="$(find "${target}" -maxdepth 1 \( ! -user user -o ! -group user \) -print 2> /dev/null)" && [[ -n ${result} ]]
}

update_ownership() {
Expand Down Expand Up @@ -181,7 +181,25 @@ if [[ ${CONTAINER_TOOL} == "docker" ]]; then
exit 1
fi

startup_cmd=(gosu user:user "${startup_cmd[@]}")
# Add DRI render group to user so gosu preserves GPU access.
# gosu sets supplementary groups from /etc/group, not from Docker's --group-add,
# so we must register the DRI device's GID in the container before dropping privileges.
# Note: do not use groupadd -f (silently no-ops if group name exists with different GID).
if [[ -d /dev/dri ]]; then
dri_gid="$(stat -c '%g' /dev/dri/renderD128 2>/dev/null || stat -c '%g' /dev/dri/card0 2>/dev/null || true)"
if [[ -n ${dri_gid} ]]; then
if ! getent group "${dri_gid}" > /dev/null 2>&1; then
groupadd -g "${dri_gid}" dri_render 2>/dev/null || true
fi
dri_group="$(getent group "${dri_gid}" | cut -d: -f1)"
if [[ -n ${dri_group} ]]; then
usermod -aG "${dri_group}" user 2>/dev/null || true
msgbox info "Added user to ${dri_group} group (gid=${dri_gid}) for DRI access"
fi
fi
fi
Comment on lines +184 to +200

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What issue is this trying to fix? Graphics card access already worked?

It does not change anything for me for egl

libEGL warning: egl: failed to create dri2 screen
libEGL warning: egl: failed to create dri2 screen
libEGL warning: egl: failed to create dri2 screen
libEGL warning: egl: failed to create dri2 screen
libEGL warning: failed to open /dev/dri/card1: Permission denied

On my machine (fedora 43), the card and render devices belong to a different group:

$ ls -al /dev/dri
total 0
drwxr-xr-x.  3 root root        100 23 mrt 09:23 .
drwxr-xr-x. 21 root root       4960 23 mrt 09:23 ..
drwxr-xr-x.  2 root root        100 23 mrt 09:23 by-path
crw-rw----+  1 root video  226,   1 23 mrt 09:23 card1
crw-rw-rw-.  1 root render 226, 128 23 mrt 09:23 renderD128

And the card is /dev/dri/card1, so we shouldn't assume it's card0?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With docker, if I add the user to the group from /dev/dri/card1 and launch with gosu user instead of gosu user:user, the permission denied warning goes away. But the other warning remains and it still uses software rendering instead of hardware rendering.


startup_cmd=(gosu user "${startup_cmd[@]}")
fi

#########################################
Expand Down
7 changes: 3 additions & 4 deletions src/update_zwift.sh
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,9 @@ install_zwift() {
msgbox info "Installing prerequisites using winetricks"
winetricks -q dotnet20 dotnet48 d3dcompiler_47 || return 1

# download and install webview 2
msgbox info "Downloading and installing webview2"
wget -O webview2-setup.exe https://go.microsoft.com/fwlink/p/?LinkId=2124703 || return 1
wine webview2-setup.exe /silent /install || return 1
# WebView2 install skipped: both bootstrapper and standalone require the
# MicrosoftEdgeUpdate COM service which Wine cannot activate. SilentLaunch
# bypasses the launcher UI so WebView2 is not needed at runtime.
Comment on lines +140 to +142

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be a specific issue with wine 11.5. It still worked with wine 11.3. But if we don't need webview2, we might indeed as well remove it.


# enable Wayland support, requires DISPLAY to be blank to use Wayland
msgbox info "Enabling Wayland support"
Expand Down
2 changes: 2 additions & 0 deletions src/zwift.sh
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,8 @@ if [[ ${window_manager} == "XWayland" ]] || [[ ${window_manager} == "XOrg" ]]; t

if [[ -d /tmp/.X11-unix ]]; then
container_args+=(-v /tmp/.X11-unix:/tmp/.X11-unix)
# Share host IPC namespace so Mesa can attach to X11 shared memory (needed for DRI2/DRI3)
container_args+=(--ipc=host)
else
msgbox error "X11 socket does not exist at /tmp/.X11-unix"
exit 1
Expand Down
Loading