---
title: System Requirements
description: RackHelm runs on a single Linux server that you control. This article lists what that server needs before you run the installer, so you can size and prepare the machine correctly. It is written for the operator who will own…
url: "https://rackhelm.com/documentation/system-requirements/"
updated: "2026-09-24"
category: "Installation & Server Setup"
---

# System Requirements

RackHelm runs on a single Linux server that you control. This article lists what that server needs before you run the installer, so you can size and prepare the machine correctly. It is written for the operator who will own the platform, not for the customers who will use it.

## Supported operating systems

The installer reads `/etc/os-release` and picks one of two package families:

| Detected | Family | Package manager | Web-server user |
| --- | --- | --- | --- |
| `ID` is `ubuntu` or `debian` | Debian | `apt-get` | `www-data` |
| `ID_LIKE` contains `rhel` or `fedora`, or `ID` is `almalinux`, `rocky` or `centos` | RHEL | `dnf` | `nginx` |
| Anything else | Unknown | — | — |

On an unrecognised distribution the installer prints a warning naming your `PRETTY_NAME` and asks **Do you want to continue anyway? (y/n)**. Answering `y` makes it fall back to Debian conventions, which will not work on a genuinely different system. The script header names Ubuntu 24.04 or newer as the target, and that is the best-tested path.

> **Note:** The installer must be run as root. It exits immediately with `Please run this script as root (sudo ./install.sh)` if the effective UID is not 0.

## PHP

The application declares `"php": "^8.2"` in `composer.json`, so PHP 8.2 is the floor. The automated installer does not use the distribution's PHP: it adds a PHP repository (`ppa:ondrej/php` on Ubuntu, `packages.sury.org` on Debian, the Remi `php:remi-8.5` module on RHEL) and installs **PHP 8.5**, recording that choice in `/var/run/rackhelm_php_version`.

These PHP packages are installed and are what the platform expects to find:

- `php-fpm` and `php-cli` — the web SAPI and the command line used by Artisan, Composer and the queue worker
- `mbstring`, `xml` (provides SimpleXML), `curl` — the three extensions `composer.json` requires outright (`ext-mbstring`, `ext-simplexml`, `ext-curl`)
- `mysql` / `mysqlnd` — database driver
- `redis` — cache, queue and session backend
- `zip`, `bcmath`, `intl`, `gd` — archives, money arithmetic, localisation and image handling
- `process` (RHEL only) — provides the `pcntl` and `posix` functions Horizon uses to manage its worker processes

The licence heartbeat additionally reports which of `curl`, `mbstring`, `intl`, `gd`, `imagick`, `zip`, `bcmath`, `redis`, `simplexml` and `sodium` are loaded, because a missing one explains most "feature X does nothing" reports.

Set `upload_max_filesize` and `post_max_size` to at least the ticket attachment limit you intend to allow. RackHelm defaults that limit to 10 MB per file.

### ionCube Loader

RackHelm ships ionCube-encoded, so the ionCube Loader must be active for *both* PHP SAPIs — FPM to serve requests, CLI to run Composer, Artisan and the queue worker. The installer downloads the Loader from ionCube, installs the non-thread-safe build matching your PHP version (`ioncube_loader_lin_8.5.so` by default), and enables it with a `zend_extension` line in a `00-ioncube.ini` file so it loads before OPcache. Only `x86_64` and `aarch64` architectures are supported; anything else aborts the install.

## Database

The installer writes `DB_CONNECTION=mysql` and configures MySQL or MariaDB:

- **Local database** — installs `mysql-server` on Debian/Ubuntu or `mariadb-server` on RHEL, creates a database and user, and generates 32-character random passwords for both the application user and the MySQL root account.
- **Remote database** — you supply host, port (default `3306`), database name, username and password. The account needs full privileges on its own database, because RackHelm creates and alters tables during upgrades.

## Redis

Redis is not optional in an installer-built deployment. The installer sets `CACHE_STORE`, `QUEUE_CONNECTION` and `SESSION_DRIVER` all to `redis`, and Laravel Horizon — which runs every provisioning, billing and email job — only works on a Redis queue. The package is `redis-server` on Debian/Ubuntu and `redis` on RHEL, listening on the default port `6379` on localhost.

## Node.js

Node is needed only to compile the front-end assets with Vite, but the install fails without it. The installer adds a signed NodeSource repository for **Node.js 22.x** and then verifies that `npm` is genuinely on the path, installing the separate `npm` package if the `nodejs` package did not bring one. If `npm` is still missing it aborts with an explicit message rather than failing later during the build.

## Other packages

`nginx`, `certbot` with `python3-certbot-nginx`, `supervisor` and `unzip` are installed as well. Composer 2 is fetched from `getcomposer.org`, checked against the vendor-published SHA-384 signature, and installed to `/usr/local/bin/composer`.

## Networking and ports

| Direction | Port | Why |
| --- | --- | --- |
| Inbound | 80/TCP | HTTP, and required for Let's Encrypt HTTP validation |
| Inbound | 443/TCP | HTTPS — the portal should only ever be used over TLS |
| Outbound | 443/TCP | Licence heartbeat to `license.orbi-hosting.com`, package repositories, payment gateways, control-panel and registrar APIs |
| Local | 3306, 6379 | MySQL/MariaDB and Redis, when installed on the same host |

The installer opens the `http` and `https` services in `firewalld`, or allows the `Nginx Full` profile in `ufw`, whichever is active. Your DNS `A` record for the portal hostname must already point at the server before you run the installer, otherwise certificate issuance fails.

## Sizing guidance

There is no hard minimum enforced in code, but the shipped worker configuration tells you what to plan for. In the `production` environment Horizon is allowed up to 10 worker processes with a 128 MB memory ceiling each, plus a 64 MB master process. Add PHP-FPM, MySQL and Redis on the same box and **4 GB of RAM is a realistic starting point**; 2 GB will run but leaves no headroom for a busy queue. For disk, budget for the operating system and PHP packages, the application tree with its `vendor/` and `node_modules/` directories, the database, and — the part that grows — `storage/app`, which holds generated invoice PDFs and ticket attachments. **40 GB** is a comfortable floor for a new install.

## File ownership model

RackHelm deliberately does not let the PHP runtime user write to its own source. After installation the whole tree is owned `root:<web user>` and mode `u=rwX,g=rX,o=`, with only `storage` and `bootstrap/cache` owned by the web user. `.env` is `root:<web user>` with mode `640`. Keep that model if you install manually — see [Manual installation](/docs/manual-installation/).

![Terminal session showing the operating system release and PHP version on a freshly prepared server](/wp-content/uploads/rackhelm-docs/installation-server-prerequisites.png)
Confirm the distribution and architecture before you start; the installer's OS detection depends on them.

## Troubleshooting

| Symptom | Cause and fix |
| --- | --- |
| `Please run this script as root` | Run the installer with `sudo`. |
| `Warning: This script is designed for Debian/Ubuntu and RHEL-based distributions` | Your distribution was not recognised. Answering `y` forces Debian conventions — only sensible on a Debian derivative that reports an unusual `ID`. |
| `Unsupported architecture … for the ionCube Loader` | The server is neither x86-64 nor ARM64. RackHelm cannot run there. |
| `ionCube did not ship ioncube_loader_lin_8.5.so` | ionCube has no Loader for that PHP version yet. Re-run with `RACKHELM_IONCUBE_PHP=8.4 sudo -E ./install.sh` against a PHP version ionCube supports. |
| `npm is not available after installing Node.js` | The Node packaging on your distribution did not provide npm. Install a Node.js 22.x distribution that includes it and re-run. |
