Switch headless display stack to Xorg dummy.

Replace Xvfb with Xorg dummy and mount /run/udev so Sunshine virtual input devices target the streamed X session instead of the host console.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-19 02:48:28 +03:00
parent 10ee14233b
commit 88b48e1796
3 changed files with 44 additions and 3 deletions

View File

@@ -12,7 +12,8 @@ RUN if [ -n "$APT_PROXY" ]; then \
# 1. Добавляем 32-битную архитектуру для Steam и базовые графические зависимости # 1. Добавляем 32-битную архитектуру для Steam и базовые графические зависимости
RUN dpkg --add-architecture i386 && \ RUN dpkg --add-architecture i386 && \
apt-get update && apt-get install -y \ apt-get update && apt-get install -y \
xvfb fluxbox dbus-x11 xauth xfonts-base x11-xserver-utils \ xserver-xorg-core xserver-xorg-video-dummy xserver-xorg-input-libinput \
fluxbox dbus-x11 xauth xfonts-base x11-xserver-utils \
software-properties-common wget curl ca-certificates locales pciutils \ software-properties-common wget curl ca-certificates locales pciutils \
libcap2-bin libgomp1 mesa-utils \ libcap2-bin libgomp1 mesa-utils \
libxcb-cursor0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 libxcb-randr0 libxcb-xtest0 \ libxcb-cursor0 libxcb-xinerama0 libxcb-xfixes0 libxcb-shape0 libxcb-randr0 libxcb-xtest0 \
@@ -48,14 +49,48 @@ RUN apt-get update && \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# 4. Скрипт очищает сессию, поднимает виртуальный экран, fluxbox и запускает Sunshine # 4. Конфиг Xorg dummy: нужен для корректной работы ввода Moonlight в контейнере
RUN mkdir -p /etc/X11 \
&& echo 'Section "ServerLayout"\n\
Identifier "Layout0"\n\
Screen 0 "Screen0"\n\
EndSection\n\
\n\
Section "Device"\n\
Identifier "Device0"\n\
Driver "dummy"\n\
VideoRam 256000\n\
EndSection\n\
\n\
Section "Monitor"\n\
Identifier "Monitor0"\n\
HorizSync 28.0-80.0\n\
VertRefresh 48.0-75.0\n\
Modeline "1920x1080" 172.80 1920 2040 2248 2576 1080 1081 1084 1118\n\
EndSection\n\
\n\
Section "Screen"\n\
Identifier "Screen0"\n\
Device "Device0"\n\
Monitor "Monitor0"\n\
DefaultDepth 24\n\
SubSection "Display"\n\
Depth 24\n\
Modes "1920x1080"\n\
EndSubSection\n\
EndSection\n\
' > /etc/X11/xorg-dummy.conf
# 5. Поднимаем Xorg dummy, fluxbox и Sunshine
RUN echo '#!/bin/bash\n\ RUN echo '#!/bin/bash\n\
set -e\n\
rm -f /tmp/.X99-lock /tmp/.X11-unix/X99\n\ rm -f /tmp/.X99-lock /tmp/.X11-unix/X99\n\
id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam\n\ id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam\n\
mkdir -p /home/steam/.local/share/Steam /tmp/xdg-steam\n\ mkdir -p /home/steam/.local/share/Steam /tmp/xdg-steam\n\
ln -sfn /home/steam/.local/share/Steam /home/steam/.steam\n\ ln -sfn /home/steam/.local/share/Steam /home/steam/.steam\n\
chown -R steam:steam /home/steam /tmp/xdg-steam\n\ chown -R steam:steam /home/steam /tmp/xdg-steam\n\
Xvfb :99 -ac -screen 0 1920x1080x24 &\n\ modprobe uinput >/dev/null 2>&1 || true\n\
Xorg :99 -config /etc/X11/xorg-dummy.conf -nolisten tcp -noreset +extension GLX +extension RANDR +extension RENDER &\n\
export DISPLAY=:99\n\ export DISPLAY=:99\n\
export HOME=/root\n\ export HOME=/root\n\
export LANG=en_US.UTF-8\n\ export LANG=en_US.UTF-8\n\

View File

@@ -70,6 +70,8 @@
`Steam Big Picture` запускается от отдельного пользователя `steam` внутри контейнера. Данные Steam сохраняются в `players/pX_steam` и не теряются после перезапуска контейнеров/сервера. `Steam Big Picture` запускается от отдельного пользователя `steam` внутри контейнера. Данные Steam сохраняются в `players/pX_steam` и не теряются после перезапуска контейнеров/сервера.
Важно: для корректной обработки ввода из Moonlight в контейнерах используется `Xorg dummy` (вместо `Xvfb`) и проброс `/run/udev` в контейнер. Это нужно, чтобы виртуальные устройства ввода Sunshine попадали в тот же X-сеанс, который стримится.
### Порты ### Порты
В Moonlight при ручном добавлении указывается один адрес в формате `IP:base_port`. В Moonlight при ручном добавлении указывается один адрес в формате `IP:base_port`.

View File

@@ -44,6 +44,7 @@ services:
volumes: volumes:
- /DATA/AppData/game-server/players/p1_steam:/home/steam/.local/share/Steam - /DATA/AppData/game-server/players/p1_steam:/home/steam/.local/share/Steam
- /DATA/AppData/game-server/players/p1_config:/root/.config/sunshine - /DATA/AppData/game-server/players/p1_config:/root/.config/sunshine
- /run/udev:/run/udev:ro
# Добавляем логирование для отладки # Добавляем логирование для отладки
logging: logging:
driver: "json-file" driver: "json-file"
@@ -67,6 +68,7 @@ services:
volumes: volumes:
- /DATA/AppData/game-server/players/p2_steam:/home/steam/.local/share/Steam - /DATA/AppData/game-server/players/p2_steam:/home/steam/.local/share/Steam
- /DATA/AppData/game-server/players/p2_config:/root/.config/sunshine - /DATA/AppData/game-server/players/p2_config:/root/.config/sunshine
- /run/udev:/run/udev:ro
logging: logging:
driver: "json-file" driver: "json-file"
options: options:
@@ -89,6 +91,7 @@ services:
volumes: volumes:
- /DATA/AppData/game-server/players/p3_steam:/home/steam/.local/share/Steam - /DATA/AppData/game-server/players/p3_steam:/home/steam/.local/share/Steam
- /DATA/AppData/game-server/players/p3_config:/root/.config/sunshine - /DATA/AppData/game-server/players/p3_config:/root/.config/sunshine
- /run/udev:/run/udev:ro
logging: logging:
driver: "json-file" driver: "json-file"
options: options:
@@ -111,6 +114,7 @@ services:
volumes: volumes:
- /DATA/AppData/game-server/players/p4_steam:/home/steam/.local/share/Steam - /DATA/AppData/game-server/players/p4_steam:/home/steam/.local/share/Steam
- /DATA/AppData/game-server/players/p4_config:/root/.config/sunshine - /DATA/AppData/game-server/players/p4_config:/root/.config/sunshine
- /run/udev:/run/udev:ro
logging: logging:
driver: "json-file" driver: "json-file"
options: options: