Files
game-server/README.md
bilal 1dd56ee73d Document current architecture and operational practices.
Update README with Steam launch scripts, shm sizing, Moonlight setup, and troubleshooting; add рекомендации.md and ignore local SSH keys.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-27 18:49:02 +03:00

203 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 сервиса player1player4
├── 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 | 4798447990 | 48010 | 4799848000 |
| player2 | 4801448020 | 48040 | 4802848030 |
| player3 | 4804448050 | 48070 | 4805848060 |
| player4 | 4807448080 | 48100 | 4808848090 |
## Конфигурация
### 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, 1020 минут). Прогресс:
```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).