# Game Server (Sunshine + Steam) Docker-конфигурация для запуска до четырёх игровых сессий через **Moonlight**. Каждый контейнер стримит виртуальный рабочий стол 1920×1080 с **Steam Big Picture** и отдельным профилем Steam на выделенном GPU. ## Архитектура ``` Moonlight → Sunshine → Xorg dummy (:99) → fluxbox + Steam (CEF) ↑ tini (PID 1, перезапуск дочерних процессов) ``` - **Sunshine v0.20.0** — стриминг и захват экрана - **Xorg dummy** — виртуальный дисплей 1920×1080 (корректный ввод из Moonlight) - **fluxbox** — панель задач внизу экрана - **Steam** — запускается от пользователя `steam` через `start-steam.sh` - **tini** — init-процесс контейнера, предотвращает zombie-процессы fluxbox ## Структура проекта ``` . ├── Dockerfile # Образ: Sunshine, Steam, Xorg, fluxbox, tini, xdotool ├── docker-compose.yml # 4 сервиса player1–player4 ├── scripts/ │ ├── entrypoint.sh # Запуск DBus, Xorg, fluxbox, Sunshine │ └── fluxbox/init # Конфиг панели задач (в образе) ├── players/ │ ├── p1_config/ # Конфиг Sunshine для player1 (монтируется в контейнер) │ │ ├── apps.json │ │ ├── start-steam.sh # Сценарий запуска Steam │ │ └── keep-steam-window.sh │ ├── p2_config/ … p4_config/ │ └── p1_steam/ … p4_steam/ # Данные Steam (не в git, создаются на сервере) ├── .env.example # Опциональный APT-прокси для сборки └── рекомендации.md # Проверенные практики эксплуатации ``` Файлы `players/pX_config/` монтируются в `/root/.config/sunshine/` — изменения скриптов применяются **без пересборки образа**. Изменения `Dockerfile` и `scripts/` требуют `docker compose build`. ## Требования - Docker и Docker Compose v2 - NVIDIA драйверы и [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) - 2× Tesla K80 (4 GPU-чипа) или аналогичная конфигурация - На хосте: `sysctl kernel.unprivileged_userns_clone=1` (нужно для Steam runtime) ## Установка 1. Склонируйте репозиторий на сервер: ```bash git clone https://git.core.com.ru/bilal/game-server.git /DATA/AppData/game-server cd /DATA/AppData/game-server ``` 2. Создайте каталоги данных Steam (если их ещё нет): ```bash mkdir -p players/p{1,2,3,4}_steam ``` 3. При необходимости измените пути volume в `docker-compose.yml` (по умолчанию `/DATA/AppData/game-server/players/...`). 4. Назначение GPU (`NVIDIA_VISIBLE_DEVICES`): | Сервис | GPU | |----------|-----| | player1 | 1 | | player2 | 2 | | player3 | 3 | | player4 | 4 | GPU `0` обычно занят отдельной видеокартой хоста и не используется игровыми контейнерами. 5. Соберите и запустите: ```bash docker compose up -d --build ``` ### APT-прокси (опционально) Для ускорения сборки через `apt-cacher-ng`: ```bash cp .env.example .env # отредактируйте APT_PROXY при необходимости docker compose up -d --build ``` ## Подключение Moonlight В Moonlight добавьте хост вручную: `IP:base_port`. | Сервис | base_port | Web UI Sunshine | |---------|-----------|-----------------| | player1 | 47989 | https://IP:47990 | | player2 | 48019 | https://IP:48019 | | player3 | 48049 | https://IP:48049 | | player4 | 48079 | https://IP:48079 | Запускайте приложение **Steam Big Picture**, не Desktop. ### Порты (host → container) | Сервис | TCP | TCP/UDP | UDP | |---------|------------------|-----------|------------------| | player1 | 47984–47990 | 48010 | 47998–48000 | | player2 | 48014–48020 | 48040 | 48028–48030 | | player3 | 48044–48050 | 48070 | 48058–48060 | | player4 | 48074–48080 | 48100 | 48088–48090 | ## Конфигурация ### Sunshine - `players/pX_config/apps.json` — список приложений Moonlight - `players/pX_config/credentials/` — TLS-сертификаты (генерируются при первом запуске, не в git) - `sunshine.conf` — создаётся автоматически при первом запуске, не хранится в репозитории ### Запуск Steam `start-steam.sh` вызывается из `apps.json` при выборе **Steam Big Picture**: 1. Проверяет и поднимает system DBus и fluxbox 2. Если Steam уже работает и UI виден — **не перезапускает** процесс 3. Иначе: чистый старт `-silent -no-cef-sandbox`, затем однократно `steam://open/gamepadui` 4. `keep-steam-window.sh` удерживает окно входа на экране и центрирует его Steam работает от пользователя `steam`; данные сохраняются в `players/pX_steam/`. ### Shared memory В `docker-compose.yml` задано `shm_size: "2gb"`. Стандартные 64 MB Docker недостаточны для CEF (Steam UI) — окно входа начинает мигать и пропадать. После изменения `shm_size` контейнер нужно **пересоздать**: ```bash docker compose up -d --force-recreate player1 ``` ### Первичная загрузка Steam При первом запуске Steam скачивает клиент (~500 MB, 10–20 минут). Прогресс: ```bash docker exec -it game-player-1 bash -lc \ 'tail -f /home/steam/.local/share/Steam/debian-installation/logs/bootstrap_log.txt' ``` После завершения снова откройте **Steam Big Picture** в Moonlight. ## Отладка ### Быстрая проверка ```bash docker compose ps docker compose logs --tail=100 player1 docker exec -it game-player-1 bash -lc ' echo "PID1: $(cat /proc/1/comm)" # должно быть tini pgrep -a sunshine pgrep -a "steam -srt" || echo "steam not running" df -h /dev/shm # должно быть ~2G, занято <20% DISPLAY=:99 xwininfo -root -tree | grep -iE "Sign in|Big Picture|1918x" ' ``` ### Логи Steam ```bash docker exec -it game-player-1 bash -lc 'tail -f /home/steam/steam-app.log' docker exec -it game-player-1 bash -lc \ 'tail -50 /home/steam/.local/share/Steam/debian-installation/logs/cef_log.txt' ``` ### Типичные проблемы | Симптом | Причина | Решение | |---------|---------|---------| | Окно входа мигает / пропадает | `/dev/shm` переполнен | `shm_size: "2gb"` + `--force-recreate` | | Нет панели задач внизу | fluxbox zombie или `-tenfoot` fullscreen | Пересоздать контейнер; не использовать `-tenfoot` | | Чёрный экран, Steam не виден | Bootstrap ещё идёт или webhelper упал | Смотреть `bootstrap_log.txt`, `webhelper-linux.txt` | | Steam перезапускается при каждом клике | Старый inline-скрипт в apps.json | Использовать `start-steam.sh` из репозитория | ### Пересборка после изменений | Что изменили | Команда | |--------------|---------| | `start-steam.sh`, `apps.json` | Достаточно перезапустить Steam в Moonlight | | `Dockerfile`, `scripts/` | `docker compose up -d --build --force-recreate player1` | | `docker-compose.yml` (shm, GPU, порты) | `docker compose up -d --force-recreate` | ## Обновление из репозитория ```bash cd /DATA/AppData/game-server git pull docker compose up -d --build ``` Скрипты в `players/pX_config/` обновятся автоматически через bind-mount. Если `git pull` перезаписал локальные правки на сервере — проверьте diff перед перезапуском. ## Дополнительно Подробные рекомендации по эксплуатации — в файле [рекомендации.md](рекомендации.md).