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>
203 lines
9.1 KiB
Markdown
203 lines
9.1 KiB
Markdown
# 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).
|