**Русский** · [English](GUIDE.en.md)

# Полная инструкция

От пустого сервера до принимающего клиентов хостинга.

**Поддерживается и развивается с помощью [REDL.IO](https://redl.io) — Хостинг с искусственным интеллектом.**

Содержание:

1. [Как всё устроено](#1-как-всё-устроено)
2. [Установка панели](#2-установка-панели)
3. [Установка игровой ноды](#3-установка-игровой-ноды)
4. [Подключение ноды к панели](#4-подключение-ноды-к-панели)
5. [Сборки игр](#5-сборки-игр)
6. [Настройка панели](#6-настройка-панели)
7. [Язык интерфейса](#7-язык-интерфейса)
8. [Капча](#8-капча)
9. [HTTPS и домен](#9-https-и-домен)
10. [Обслуживание](#10-обслуживание)
11. [Если что-то не работает](#11-если-что-то-не-работает)

---

## 1. Как всё устроено

Две роли, обычно на разных машинах:

**Панель** — сайт, база данных, личные кабинеты, тикеты, платежи. Docker ей не нужен,
живёт на любом дешёвом VPS.

**Игровая нода (локация)** — здесь запускаются сами игровые сервера. Панель подключается к ней
**по SSH** и на каждый заказанный сервер создаёт отдельный Docker-контейнер:

```
docker create --tty --rm --name=gs<ID> --network=host \
  --cpus="<ядра>" --memory=<ОЗУ>M \
  --volume="/home/gs<ID>/:/home/container/" \
  --workdir=/home/container debian:stretch
```

Отсюда два жёстких требования к ноде: **работающий Docker** и **локальный образ с тегом
`debian:stretch`** (имя прописано в коде панели). Файлы сервера лежат на ноде в `/home/gs<ID>`,
внутри контейнера они видны как `/home/container`.

Нод может быть несколько — они добавляются в панели как отдельные локации, клиент выбирает
локацию при заказе.

> **Важно про ноду.** Docker не запускается в контейнерных VPS (LXC, OpenVZ и подобные) —
> ядро запрещает вложенные namespace. Под ноду нужен **выделенный сервер или KVM**.
> Установщик проверяет это первым делом и предупреждает.

---

## 2. Установка панели

Подходит Ubuntu 24.04 / 22.04 или Debian 12 / 13. Минимум: 1 ядро, 1 ГБ ОЗУ, 10 ГБ диска.

```bash
apt-get update && apt-get install -y git
git clone https://github.com/RedlHosting/redl-gamepanel.git
cd redl-gamepanel
sudo bash install-panel.sh
```

Скрипт спросит три вещи:

* **домен или IP панели** — попадёт в конфиг как базовый адрес, с него формируются все ссылки
  и письма;
* **e-mail администратора** — он же логин;
* **пароль администратора** — минимум 6 символов.

Дальше без вашего участия: пакеты, база со случайным паролем, схема (27 таблиц), конфиг,
права, PHP, nginx, планировщик, сторож автозапуска, администратор с полным уровнем доступа,
финальная проверка страницы входа.

Занимает 2–5 минут. В конце печатается адрес панели и логин.

**Нестандартный порт** (если 80 занят или панель за обратным прокси):

```bash
sudo PORT=8095 bash install-panel.sh
```

**Где что лежит после установки:**

| Что | Путь |
|-----|------|
| Код панели | `/var/www/hostinpl` |
| Конфигурация | `/var/www/hostinpl/application/config.php` |
| Пароль БД и токен планировщика | `/root/.redl-panel-credentials` |
| Конфиг nginx | `/etc/nginx/sites-available/hostinpl` |
| Планировщик | `/etc/cron.d/hostinpl` |
| Сторож автозапуска | `/usr/local/bin/hostinpl-guard` |
| База данных | MariaDB, база `hostin` |

**phpMyAdmin** (по желанию, панель ссылается на него из админки):

```bash
sudo apt-get install -y phpmyadmin        # веб-сервер настраивать НЕ надо, откажитесь
sudo ln -sfn /usr/share/phpmyadmin /var/www/hostinpl/phpmyadmin
```

Логин — пользователь БД из `/root/.redl-panel-credentials`. Помните, что phpMyAdmin будет
доступен всем, кто знает адрес: либо закройте его в nginx по IP, либо не ставьте вообще.

---

## 3. Установка игровой ноды

Нужен **выделенный сервер или KVM** (не LXC/OpenVZ). Минимум: 2 ядра, 2 ГБ ОЗУ, 100 ГБ диска,
считайте 1–2 ГБ на игровой сервер.

```bash
apt-get update && apt-get install -y git
git clone https://github.com/RedlHosting/redl-gamepanel.git
cd redl-gamepanel
sudo bash install-node.sh
```

Скрипт спросит:

* **IP этой ноды** — как её увидит панель;
* **разрешить ли вход root по SSH с паролем** — панель умеет подключаться только логином и
  паролем, а её команды требуют прав root. Ответите `yes` — скрипт сам сгенерирует стойкий
  пароль root и покажет его в конце.

Что делает: проверяет пригодность машины, ставит Docker из официального репозитория, собирает
образ `debian:stretch` (внутри Debian 12 + 32-битные библиотеки + Java + Node.js + screen),
создаёт `/home/cp/gameservers/files` и группу `gameservers`, ставит MariaDB для баз игровых
серверов, SteamCMD, ProFTPD, настраивает sshd, ставит сторож Docker.

Первый запуск идёт 5–15 минут — большую часть времени собирается образ.

**Сразу после установки закройте порты.** Скрипт напечатает готовые команды, подставьте адрес
панели:

```bash
ufw allow from IP_ПАНЕЛИ to any port 22 proto tcp
ufw allow from IP_ПАНЕЛИ to any port 3306 proto tcp
ufw deny 3306
# порты игровых серверов оставьте открытыми: 7777 (SA-MP), 22005 (RAGE:MP), 25565 (Minecraft) и т.д.
```

Если подключаетесь к ноде по SSH сами — **сначала разрешите свой IP**, иначе потеряете доступ:

```bash
ufw allow from ВАШ_IP to any port 22 proto tcp
```

---

## 4. Подключение ноды к панели

1. Войдите в панель администратором
2. **Админка → Локации → Добавить локацию**
3. Заполните:

| Поле | Что вписать |
|------|-------------|
| Название | Любое понятное: «Москва», «Хельсинки» |
| IP | IP ноды |
| Пользователь | `root` |
| Пароль | Пароль root, который напечатал `install-node.sh` |
| Игры | Отметьте игры, доступные на этой ноде |

4. Сохраните и откройте **Админка → Локации** — если панель подключилась, у локации появятся
   реальные ядра, ОЗУ и диск (обновляются планировщиком раз в час).

Не подключилось — проверьте с машины панели:

```bash
ssh root@IP_НОДЫ                      # пароль подходит?
php -m | grep ssh2                    # расширение php-ssh2 стоит?
```

Расширения нет — `apt-get install -y php-ssh2` и перезапустите PHP-FPM.

---

## 5. Сборки игр

**В комплект они не входят.** В оригинальном установщике сборки качались с посторонних сайтов
по обычному HTTP без проверки подписи — мы этот способ убрали (подробно в
[БЕЗОПАСНОСТЬ.md](БЕЗОПАСНОСТЬ.md)).

Разложите файлы на ноде так:

```
/home/cp/gameservers/files/<код_игры>/
```

Коды игр смотрите в **Админка → Игры** (например `samp`, `crmp`, `mta`, `minecraft`, `cs`, `css`, `ragemp`).
При создании сервера панель копирует содержимое этого каталога в `/home/gs<ID>/`.

Берите сборки только из первоисточников: SA-MP — с `sa-mp.com`, MTA — с `mtasa.com`,
Minecraft (Paper) — с `papermc.io`, RAGE:MP — с `rage.mp`, игры Steam — через SteamCMD
(уже установлен в `/root/steamcmd`).

После этого проверьте цепочку целиком: закажите сервер от имени тестового клиента и убедитесь,
что он создался и запустился.

---

## 6. Настройка панели

**Админка → Настройки**, четыре вкладки:

* **Общие настройки** — название, описание, контакты, логотип
* **Платёжные системы** — Unitpay, Enot, AnyPay, LiteKassa, RoboKassa, FreeKassa, Юkassa, QIWI.
  Нужны ваши мерчант-аккаунты. Ни один шлюз мы живыми платежами не проверяли — обязательно
  протестируйте своим платежом перед приёмом клиентов.
* **Прочие настройки** — тестовый период, подтверждение e-mail, **капча**, техработы, VK-авторизация
* **Информация и бонусы** — бонусы за пополнение, реферальные проценты

Тарифы и игры: **Админка → Игры** (версии, лимиты ОЗУ и ядер, цены).

> При сохранении настроек панель перезаписывает `config.php` целиком. Механизм ищет строки
> **по подстроке**, поэтому не создавайте параметры, чьи имена являются частью других.
> После правки файла руками перезапускайте PHP-FPM **полностью** (`restart`, не `reload`) —
> иначе отдаётся закешированная версия.

---

## 7. Язык интерфейса

Панель говорит на **русском и английском**. Язык выбирается в таком порядке:

1. `?lang=en` или `?lang=ru` в адресе — явный выбор, запоминается в cookie на год
2. cookie `lang` — прошлый выбор
3. **заголовок браузера `Accept-Language`** — автоопределение
4. параметр `lang` в `application/config.php` (по умолчанию `ru`)

Автоопределение намеренно оставляет русский для русскоязычных локалей (ru, uk, be, kk и других)
и переключает на английский для всех остальных — то есть посетитель из Германии или Бразилии
сразу получает английский интерфейс, ничего не нажимая.

**Переключатель** стоит в верхней панели кабинета и админки (кнопки `RU` / `EN` рядом с балансом)
и в подвале страницы входа.

**Как это сделано.** Панель написана с русским текстом прямо в шаблонах — около 1500 строк в
200 файлах. Вместо того чтобы переписывать их все, перевод применяется к готовому ответу:
`index.php` оборачивает вывод в `ob_start()`, и перед отправкой браузеру строки заменяются по
словарю (`engine/main/lang.php`). Это разом покрывает всю панель, включая админку и письма, а
фразы, которых нет в словаре, просто остаются русскими — ничего не может пропасть с экрана.

Замена работает **только на границах слов**, поэтому короткий ключ не может испортить слово
подлиннее (без этого «Мод» превращал «Модуль» в «Modуль»).

**Как добавить свой язык**, например немецкий:

```bash
cp panel/application/lang/en.php panel/application/lang/de.php
# перевести значения в de.php, затем добавить 'de' в Lang::AVAILABLE
# в panel/engine/main/lang.php
```

Полноту словаря мы проверяли обходом страниц: все 20 разделов, которые проходим, отдаются без
остатков русского текста. Если увидите непереведённую фразу — допишите её в
`application/lang/en.php`, ключ это русский текст ровно в том виде, в каком он на странице.

Перевод включается только когда язык не русский; в русском режиме словарь даже не загружается,
поэтому накладных расходов нет.

---

## 8. Капча

По умолчанию **выключена** — регистрация и вход работают без неё, поля просто нет.

Чтобы включить:

1. Получите ключи reCAPTCHA **v2 «Я не робот»** на
   [google.com/recaptcha/admin](https://www.google.com/recaptcha/admin) — укажите домен панели
2. **Админка → Настройки → Прочие настройки → «Защита от ботов (reCAPTCHA v2)»**
3. Вставьте **Site key** и **Secret key**
4. Переключите на «Включена» и сохраните

**Порядок важен.** Включите капчу без ключей — на форме появится
«ERROR for site owner: Invalid site key», и войти будет нельзя. Если так вышло, откройте
`/var/www/hostinpl/application/config.php`, поставьте `'captcha_enable' => '0'` и перезапустите
PHP-FPM:

```bash
sudo sed -i "s/'captcha_enable' => '1'/'captcha_enable' => '0'/" /var/www/hostinpl/application/config.php
sudo service php8.4-fpm restart     # подставьте свою версию PHP
```

Капча закрывает вход, регистрацию, восстановление пароля и создание тикетов — все четыре формы
сразу.

---

## 9. HTTPS и домен

Панель ставится на HTTP. Для сертификата:

```bash
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d panel.example.com
```

После выпуска сертификата поправьте адрес в конфиге, иначе ссылки в письмах и редиректы
останутся на `http://`:

```bash
sudo sed -i "s|'url' => 'http://|'url' => 'https://|" /var/www/hostinpl/application/config.php
sudo service php8.4-fpm restart
```

Если панель за обратным прокси (Caddy, nginx, Cloudflare), в её конфиге nginx уже стоят
`absolute_redirect off; port_in_redirect off;` — без них редиректы уводят на внутренний порт
и ссылки вроде `/phpmyadmin` снаружи не открываются.

---

## 10. Обслуживание

**Резервные копии.** Сохраняйте базу и конфиг:

```bash
mysqldump hostin > /root/hostin-$(date +%F).sql
cp /var/www/hostinpl/application/config.php /root/config-$(date +%F).php
```

Файлы игровых серверов лежат на ноде в `/home/gs<ID>` — их бэкапьте на ноде.

**Логи:**

| Что смотреть | Где |
|--------------|-----|
| Ошибки PHP и nginx | `/var/log/nginx/error.log` |
| Обращения планировщика | `grep 'main/cron' /var/log/nginx/access.log` |
| Журнал входов | Таблица `authlog` в базе |
| Сборка образа ноды | `/tmp/redl-docker-build.log` |

**Проверка состояния:** **Админка → Проверка системы** — расширения PHP, версии, ссылки
планировщика. Все пункты должны быть зелёными.

**Обновление кода** из репозитория:

```bash
cd redl-gamepanel && git pull
sudo cp -a panel/application panel/engine /var/www/hostinpl/     # config.php не перезапишется
sudo chown -R www-data:www-data /var/www/hostinpl
sudo service php8.4-fpm restart
```

---

## 11. Если что-то не работает

**«Ошибка: Не удалось загрузить контроллер …»** — панель не нашла контроллер для этого адреса.
Обычно это ссылка на то, чего нет: например `/phpmyadmin`, когда phpMyAdmin не установлен
(см. раздел 2). Если раздел точно должен быть — проверьте, что файлы на месте и права `www-data`,
затем перезапустите PHP-FPM **полностью**: `opcache` мог закешировать файл, пойманный в момент записи.

**Страница входа пустая или без формы** — смотрите `/var/log/nginx/error.log`.
Частая причина: `short_open_tag = Off`. Панель использует короткие теги `<? ?>`, установщик
включает эту опцию сам, но при переустановке PHP её нужно вернуть.

**Не могу войти, на форме «Invalid site key»** — включена капча без ключей, см. раздел 8.

**Планировщик не работает** (статистика не обновляется, просроченные сервера не отключаются):

```bash
grep -c 'main/cron' /var/log/nginx/access.log     # должно расти
pgrep -a cron                                     # демон запущен?
cat /etc/cron.d/hostinpl                          # каждое задание — ОДНОЙ строкой
```

Если задание разорвано на две строки — токен попал в файл с переводом строки, перепишите файл
целиком, взяв токен из `/root/.redl-panel-credentials`.

**Сервер не создаётся на ноде** — проверьте на ноде:

```bash
docker info                                  # демон работает?
docker image inspect debian:stretch          # образ на месте?
docker run --rm debian:stretch echo ok       # контейнер запускается?
ls /home/cp/gameservers/files/               # сборка игры на месте?
```

**Сервер создался, но сразу падает** — смотрите логи контейнера на ноде:
`docker logs gs<ID>`. Чаще всего не хватает 32-битных библиотек (тогда пересоберите образ
из нашего `docker/Dockerfile`) или сборка игры повреждена.

**Всё было хорошо, перестало после перезагрузки** — на машинах без systemd подъём делают
сторожа на cron. Проверьте: `pgrep -a cron` и вручную `/usr/local/bin/hostinpl-guard`
(на ноде — `gamenode-guard`).

---

**Поддерживается и развивается с помощью [REDL.IO](https://redl.io) — Хостинг с искусственным интеллектом.**
