[Русский](ИНСТРУКЦИЯ.md) · **English** # 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 --network=host \ --cpus="" --memory=M \ --volume="/home/gs/:/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` 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 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/`. 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 ``` Dictionary coverage is verified by crawling the pages: all 20 sections we walk through render with no Russian left over. If you spot an untranslated phrase, add it to `application/lang/en.php` — the key is the Russian text exactly as it appears. 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` — 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`. 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.**