Из названий было не видно, какая панель лежит в основе. Теперь версия стоит в H1 всех документов и галерей, а в начале README (обоих) добавлена строка об оригинале: HostinPL 5.6, авторы Samir Shelenko и Alexander Zemlyanoy, писалась под Debian 9 / PHP 7.0. Нумерация версии оставлена от оригинала. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
412 lines
16 KiB
Markdown
412 lines
16 KiB
Markdown
[Русский](ИНСТРУКЦИЯ.md) · **English**
|
||
|
||
# HostinPL 5.6 · Complete guide
|
||
|
||
From an empty server to a hosting service that can take clients.
|
||
|
||
**Maintained and developed with [REDL.IO](https://redl.io) — AI-powered hosting.**
|
||
|
||
Contents:
|
||
|
||
1. [How it all fits together](#1-how-it-all-fits-together)
|
||
2. [Installing the panel](#2-installing-the-panel)
|
||
3. [Installing a game node](#3-installing-a-game-node)
|
||
4. [Connecting the node to the panel](#4-connecting-the-node-to-the-panel)
|
||
5. [Game server files](#5-game-server-files)
|
||
6. [Configuring the panel](#6-configuring-the-panel)
|
||
7. [Interface language](#7-interface-language)
|
||
8. [Captcha](#8-captcha)
|
||
9. [HTTPS and domain](#9-https-and-domain)
|
||
10. [Maintenance](#10-maintenance)
|
||
11. [Troubleshooting](#11-troubleshooting)
|
||
|
||
---
|
||
|
||
## 1. How it all fits together
|
||
|
||
Two roles, usually on separate machines:
|
||
|
||
**The panel** — the website, the database, client areas, tickets, payments. It does not need Docker
|
||
and runs happily on a cheap VPS.
|
||
|
||
**A game node (location)** — where the game servers themselves run. The panel connects to it
|
||
**over SSH** and creates a separate Docker container for every ordered server:
|
||
|
||
```
|
||
docker create --tty --rm --name=gs<ID> --network=host \
|
||
--cpus="<cores>" --memory=<RAM>M \
|
||
--volume="/home/gs<ID>/:/home/container/" \
|
||
--workdir=/home/container debian:stretch
|
||
```
|
||
|
||
Hence two hard requirements for a node: **working Docker** and **a local image tagged
|
||
`debian:stretch`** (the name is hard-coded in the panel). Server files live on the node in
|
||
`/home/gs<ID>` and appear inside the container as `/home/container`.
|
||
|
||
You can have several nodes — they are added to the panel as separate locations, and the client
|
||
picks one when ordering.
|
||
|
||
> **Important about nodes.** Docker does not start inside container-based VPSes (LXC, OpenVZ and
|
||
> similar) because the kernel forbids nested namespaces. A node needs **a dedicated server or KVM**.
|
||
> The installer checks this first and warns you.
|
||
|
||
---
|
||
|
||
## 2. Installing the panel
|
||
|
||
Ubuntu 24.04 / 22.04 or Debian 12 / 13. Minimum: 1 core, 1 GB RAM, 10 GB disk.
|
||
|
||
```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
|
||
```
|
||
|
||
The script asks three things:
|
||
|
||
* **the panel's domain or IP** — it goes into the configuration as the base address, and all links
|
||
and e-mails are built from it;
|
||
* **the administrator e-mail** — also the login;
|
||
* **the administrator password** — at least 6 characters.
|
||
|
||
Everything after that is automatic: packages, a database with a random password, the schema
|
||
(27 tables), configuration, permissions, PHP, nginx, the scheduler, an autostart watchdog, an
|
||
administrator with full access, and a final check that the login page opens.
|
||
|
||
It takes 2–5 minutes. The panel address and login are printed at the end.
|
||
|
||
**A non-standard port** (if 80 is taken, or the panel sits behind a reverse proxy):
|
||
|
||
```bash
|
||
sudo PORT=8095 bash install-panel.sh
|
||
```
|
||
|
||
**Where things end up:**
|
||
|
||
| What | Path |
|
||
|------|------|
|
||
| Panel code | `/var/www/hostinpl` |
|
||
| Configuration | `/var/www/hostinpl/application/config.php` |
|
||
| Database password and scheduler token | `/root/.redl-panel-credentials` |
|
||
| nginx configuration | `/etc/nginx/sites-available/hostinpl` |
|
||
| Scheduler | `/etc/cron.d/hostinpl` |
|
||
| Autostart watchdog | `/usr/local/bin/hostinpl-guard` |
|
||
| Database | MariaDB, database `hostin` |
|
||
|
||
**phpMyAdmin** (optional; the panel links to it from the admin area):
|
||
|
||
```bash
|
||
sudo apt-get install -y phpmyadmin # do NOT let it configure a web server, decline
|
||
sudo ln -sfn /usr/share/phpmyadmin /var/www/hostinpl/phpmyadmin
|
||
```
|
||
|
||
Log in with the database user from `/root/.redl-panel-credentials`. Remember that phpMyAdmin will be
|
||
reachable by anyone who knows the address: either restrict it by IP in nginx, or do not install it.
|
||
|
||
---
|
||
|
||
## 3. Installing a game node
|
||
|
||
You need **a dedicated server or KVM** (not LXC/OpenVZ). Minimum: 2 cores, 2 GB RAM, 100 GB disk,
|
||
counting 1–2 GB per game server.
|
||
|
||
```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
|
||
```
|
||
|
||
The script asks:
|
||
|
||
* **this node's IP** — how the panel will reach it;
|
||
* **whether to allow root SSH login with a password** — the panel can only connect with a login and
|
||
password, and its commands require root. Answer `yes` and the script generates a strong root
|
||
password and shows it at the end.
|
||
|
||
What it does: checks that the machine is suitable, installs Docker from the official repository,
|
||
builds the `debian:stretch` image (Debian 12 inside, plus 32-bit libraries, Java, Node.js and
|
||
screen), creates `/home/cp/gameservers/files` and the `gameservers` group, installs MariaDB for game
|
||
server databases, SteamCMD and ProFTPD, configures sshd, and installs a Docker watchdog.
|
||
|
||
The first run takes 5–15 minutes, mostly building the image.
|
||
|
||
**Close the ports immediately afterwards.** The script prints ready-made commands; substitute the
|
||
panel's address:
|
||
|
||
```bash
|
||
ufw allow from PANEL_IP to any port 22 proto tcp
|
||
ufw allow from PANEL_IP to any port 3306 proto tcp
|
||
ufw deny 3306
|
||
# leave the game ports open: 7777 (SA-MP), 22005 (RAGE:MP), 25565 (Minecraft) and so on
|
||
```
|
||
|
||
If you also connect to the node over SSH yourself, **allow your own IP first** or you will lock
|
||
yourself out:
|
||
|
||
```bash
|
||
ufw allow from YOUR_IP to any port 22 proto tcp
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Connecting the node to the panel
|
||
|
||
1. Sign in to the panel as an administrator
|
||
2. Go to **Admin → Locations → Add location**
|
||
3. Fill in:
|
||
|
||
| Field | What to enter |
|
||
|-------|---------------|
|
||
| Name | Anything meaningful: "Frankfurt", "Helsinki" |
|
||
| IP | The node's IP |
|
||
| User | `root` |
|
||
| Password | The root password printed by `install-node.sh` |
|
||
| Games | Tick the games available on this node |
|
||
|
||
4. Save and open **Admin → Locations** — if the panel connected, the location shows its real cores,
|
||
RAM and disk (refreshed hourly by the scheduler).
|
||
|
||
If it does not connect, check from the panel machine:
|
||
|
||
```bash
|
||
ssh root@NODE_IP # does the password work?
|
||
php -m | grep ssh2 # is the php-ssh2 extension installed?
|
||
```
|
||
|
||
If the extension is missing: `apt-get install -y php-ssh2`, then restart PHP-FPM.
|
||
|
||
---
|
||
|
||
## 5. Game server files
|
||
|
||
**They are not included.** The original installer downloaded them from third-party sites over plain
|
||
HTTP with no signature checking, so we removed that (details in [SECURITY.en.md](SECURITY.en.md)).
|
||
|
||
Lay the files out on the node like this:
|
||
|
||
```
|
||
/home/cp/gameservers/files/<game_code>/
|
||
```
|
||
|
||
Game codes are listed under **Admin → Games** (for example `samp`, `crmp`, `mta`, `minecraft`,
|
||
`cs`, `css`, `ragemp`). When a server is created, the panel copies the contents of that directory
|
||
into `/home/gs<ID>/`.
|
||
|
||
Only take builds from primary sources: SA-MP from `sa-mp.com`, MTA from `mtasa.com`,
|
||
Minecraft (Paper) from `papermc.io`, RAGE:MP from `rage.mp`, Steam games via SteamCMD
|
||
(already installed in `/root/steamcmd`).
|
||
|
||
Then test the whole chain: order a server as a test client and confirm that it is created and starts.
|
||
|
||
---
|
||
|
||
## 6. Configuring the panel
|
||
|
||
**Admin → Settings**, four tabs:
|
||
|
||
* **General settings** — name, description, contacts, logo
|
||
* **Payment gateways** — Unitpay, Enot, AnyPay, LiteKassa, RoboKassa, FreeKassa, YooKassa, QIWI.
|
||
You need your own merchant accounts. We never tested a gateway with a real payment — test each one
|
||
with your own money before taking clients.
|
||
* **Other settings** — trial period, e-mail confirmation, **captcha**, maintenance mode, VK login
|
||
* **Information and bonuses** — top-up bonuses, referral percentages
|
||
|
||
Plans and games live under **Admin → Games** (versions, RAM and core limits, prices).
|
||
|
||
> When you save settings the panel rewrites `config.php` entirely. It matches configuration lines
|
||
> **by substring**, so do not create parameters whose names are contained in other names.
|
||
> After editing the file by hand, restart PHP-FPM **fully** (`restart`, not `reload`) — otherwise a
|
||
> cached copy is served.
|
||
|
||
---
|
||
|
||
## 7. Interface language
|
||
|
||
The panel speaks **Russian and English**. The language is chosen in this order:
|
||
|
||
1. `?lang=en` or `?lang=ru` in the URL — an explicit choice, remembered in a cookie for a year
|
||
2. the `lang` cookie — the previous choice
|
||
3. **the browser's `Accept-Language` header** — automatic detection
|
||
4. the `lang` value in `application/config.php` (default `ru`)
|
||
|
||
Automatic detection deliberately keeps Russian for Russian-speaking locales (ru, uk, be, kk and
|
||
others) and switches to English for everything else, so a visitor from Germany or Brazil gets the
|
||
English interface without touching anything.
|
||
|
||
**The switcher** sits in the top bar of the client area and the admin area (the `RU` / `EN` buttons
|
||
next to the balance) and in the footer of the login page.
|
||
|
||
**How it is built.** The panel was written with Russian text directly in the templates — about
|
||
1500 strings across 200 files. Instead of rewriting all of them, translation happens on the finished
|
||
response: `index.php` wraps the output in `ob_start()`, and before the page is sent to the browser
|
||
the strings are replaced using a dictionary (`engine/main/lang.php`). This covers the whole panel at
|
||
once, including the admin area and e-mails, and anything missing from the dictionary simply stays
|
||
Russian — nothing can vanish from the screen.
|
||
|
||
Replacement only happens on word boundaries, so a short dictionary key cannot corrupt a longer word.
|
||
|
||
**Adding your own language**, for example German:
|
||
|
||
```bash
|
||
cp panel/application/lang/en.php panel/application/lang/de.php
|
||
# translate the values in de.php, then add 'de' to Lang::AVAILABLE
|
||
# in panel/engine/main/lang.php
|
||
```
|
||
|
||
**Coverage.** The dictionary holds 1304 phrases and covers everything a person sees: the client area,
|
||
ordering, server management (console with all RCON commands, FTP, MySQL, firewall, scheduler,
|
||
mod auto-install), tickets, the whole FAQ, the entire admin area, and the e-mail templates. Coverage
|
||
is measured, not assumed — a script replays the replacement logic against the sources and reports
|
||
what would stay Russian; a live crawl of 45 pages in English mode confirms it. Four items remain
|
||
Russian on purpose: the "Русский" label of the switcher itself, the two game-server language codes
|
||
in the FAQ (`rus => Pyccĸий`, `ukr => Українська`), and a name-validation regular expression.
|
||
|
||
If you do spot an untranslated phrase, add it to `application/lang/en.php` — the key is the Russian
|
||
text exactly as it appears in the output. Two rules worth knowing:
|
||
|
||
* **never add a standalone function word** (a preposition or conjunction such as `в`). It gets
|
||
substituted inside sentences that are not translated yet and produces mixed-language nonsense
|
||
like "at поле имя пользователя". Translate such words as part of the whole phrase.
|
||
* if the phrase contains a PHP variable, use the static fragments around it as separate keys — the
|
||
rendered text has real values in place of the variable and the full string would never match.
|
||
|
||
See the [screenshot gallery](docs/screenshots/README.md) for every section in both languages.
|
||
|
||
Translation only runs when the language is not Russian; in Russian mode the dictionary is not even
|
||
loaded, so there is no overhead.
|
||
|
||
---
|
||
|
||
## 8. Captcha
|
||
|
||
By default it is **off** — registration and login work without it, and the field is simply absent.
|
||
|
||
To enable it:
|
||
|
||
1. Get **reCAPTCHA v2 "I'm not a robot"** keys at
|
||
[google.com/recaptcha/admin](https://www.google.com/recaptcha/admin) and specify the panel's domain
|
||
2. Go to **Admin → Settings → Other settings → "Bot protection (reCAPTCHA v2)"**
|
||
3. Paste the **Site key** and the **Secret key**
|
||
4. Switch to "Enabled" and save
|
||
|
||
**The order matters.** Enable the captcha without keys and the form will show
|
||
"ERROR for site owner: Invalid site key", locking everyone out. If that happens, open
|
||
`/var/www/hostinpl/application/config.php`, set `'captcha_enable' => '0'` and restart 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 # use your PHP version
|
||
```
|
||
|
||
The captcha covers login, registration, password recovery and ticket creation — all four forms at once.
|
||
|
||
---
|
||
|
||
## 9. HTTPS and domain
|
||
|
||
The panel is installed over HTTP. For a certificate:
|
||
|
||
```bash
|
||
sudo apt-get install -y certbot python3-certbot-nginx
|
||
sudo certbot --nginx -d panel.example.com
|
||
```
|
||
|
||
After the certificate is issued, update the address in the configuration, otherwise links in
|
||
e-mails and redirects will stay on `http://`:
|
||
|
||
```bash
|
||
sudo sed -i "s|'url' => 'http://|'url' => 'https://|" /var/www/hostinpl/application/config.php
|
||
sudo service php8.4-fpm restart
|
||
```
|
||
|
||
If the panel sits behind a reverse proxy (Caddy, nginx, Cloudflare), its nginx configuration already
|
||
contains `absolute_redirect off; port_in_redirect off;` — without them redirects point at the
|
||
internal port and links such as `/phpmyadmin` do not open from outside.
|
||
|
||
---
|
||
|
||
## 10. Maintenance
|
||
|
||
**Backups.** Keep the database and the configuration:
|
||
|
||
```bash
|
||
mysqldump hostin > /root/hostin-$(date +%F).sql
|
||
cp /var/www/hostinpl/application/config.php /root/config-$(date +%F).php
|
||
```
|
||
|
||
Game server files live on the node in `/home/gs<ID>` — back those up on the node.
|
||
|
||
**Logs:**
|
||
|
||
| What to look at | Where |
|
||
|-----------------|-------|
|
||
| PHP and nginx errors | `/var/log/nginx/error.log` |
|
||
| Scheduler hits | `grep 'main/cron' /var/log/nginx/access.log` |
|
||
| Login journal | the `authlog` table |
|
||
| Node image build | `/tmp/redl-docker-build.log` |
|
||
|
||
**Health check:** **Admin → System check** — PHP extensions, versions, scheduler links. Every item
|
||
should be green.
|
||
|
||
**Updating the code** from the repository:
|
||
|
||
```bash
|
||
cd redl-gamepanel && git pull
|
||
sudo cp -a panel/application panel/engine /var/www/hostinpl/ # config.php is not overwritten
|
||
sudo chown -R www-data:www-data /var/www/hostinpl
|
||
sudo service php8.4-fpm restart
|
||
```
|
||
|
||
---
|
||
|
||
## 11. Troubleshooting
|
||
|
||
**"Error: could not load the controller …"** — the panel found no controller for that address.
|
||
Usually it is a link to something that does not exist, for example `/phpmyadmin` when phpMyAdmin is
|
||
not installed (see section 2). If the section really should exist, check that the files are in place
|
||
and owned by `www-data`, then restart PHP-FPM **fully**: opcache may have cached a file that was
|
||
caught mid-write.
|
||
|
||
**The login page is blank or has no form** — look at `/var/log/nginx/error.log`. A common cause is
|
||
`short_open_tag = Off`. The panel uses short `<? ?>` tags; the installer turns the option on, but you
|
||
have to restore it if you reinstall PHP.
|
||
|
||
**Cannot log in, the form shows "Invalid site key"** — the captcha is on without keys, see section 8.
|
||
|
||
**The scheduler is not running** (statistics not updating, expired servers not suspended):
|
||
|
||
```bash
|
||
grep -c 'main/cron' /var/log/nginx/access.log # should grow
|
||
pgrep -a cron # is the daemon running?
|
||
cat /etc/cron.d/hostinpl # every job must be on ONE line
|
||
```
|
||
|
||
If a job is split across two lines, the token got into the file with a newline — rewrite the file,
|
||
taking the token from `/root/.redl-panel-credentials`.
|
||
|
||
**A server is not created on the node** — check on the node:
|
||
|
||
```bash
|
||
docker info # is the daemon up?
|
||
docker image inspect debian:stretch # is the image there?
|
||
docker run --rm debian:stretch echo ok # does a container start?
|
||
ls /home/cp/gameservers/files/ # are the game files in place?
|
||
```
|
||
|
||
**The server is created but dies immediately** — look at the container log on the node:
|
||
`docker logs gs<ID>`. Most often the 32-bit libraries are missing (rebuild the image from our
|
||
`docker/Dockerfile`) or the game build is damaged.
|
||
|
||
**Everything worked until a reboot** — on machines without systemd, the watchdogs on cron bring
|
||
things back. Check `pgrep -a cron` and run `/usr/local/bin/hostinpl-guard` by hand
|
||
(`gamenode-guard` on a node).
|
||
|
||
**A phrase in the interface is still Russian in English mode** — add it to
|
||
`panel/application/lang/en.php`; the key is the Russian text exactly as it appears on the page.
|
||
|
||
---
|
||
|
||
**Maintained and developed with [REDL.IO](https://redl.io) — AI-powered hosting.**
|