When install.sh stops, it prints the stage that failed and the log file to read. This article lists every message the installer can produce, what it means, and what to do next — plus the problems that appear after a technically successful install.
Where the logs are #
Each stage writes to its own file. All of them are set to mode 600 because they contain database passwords.
| Log file | Stage |
|---|---|
/var/log/rackhelm_install_sys.log |
OS packages, repositories, Composer, ionCube Loader |
/var/log/rackhelm_install_deploy.log |
Copying the application into /var/www/rackhelm |
/var/log/rackhelm_install_env.log |
Writing .env |
/var/log/rackhelm_install_composer.log |
composer install |
/var/log/rackhelm_install_npm.log |
npm install and npm run build |
/var/log/rackhelm_install_mysql_config.log |
Local database, user and root password |
/var/log/rackhelm_install_servers.log |
nginx, Supervisor, firewall, certbot |
/var/log/rackhelm_install_artisan.log |
Migrations, seeding, view cache, storage link (admin password redacted) |
/var/log/rackhelm_install_perms.log |
Final ownership and permissions |
Four of these stages run at the same time. When one of them fails the installer prints the names of the threads that broke, for example Failed stage(s): npm servers, followed by the exact log paths — so you do not have to work it out from timestamps.

Pre-flight failures #
| Message | Meaning and fix |
|---|---|
Please run this script as root (sudo ./install.sh) |
Run it with sudo. |
Warning: This script is designed for Debian/Ubuntu and RHEL-based distributions. |
Your /etc/os-release was not recognised. Answering y continues with Debian conventions; on a non-Debian system that will fail during package installation. |
This installer must be run from the extracted release directory. |
The installer looks for artisan and .env.example beside itself. You have copied install.sh out of the archive — change into the extracted directory and run it there. |
System prerequisites stage #
| Message | Meaning and fix |
|---|---|
npm is not available after installing Node.js… |
The nodejs package that won the apt or dnf resolution did not bundle npm, and the separate npm package could not be installed either. Install a Node.js 22.x distribution that provides npm, then re-run. |
Composer installer checksum mismatch; refusing to run it. |
The file downloaded from getcomposer.org did not match the published SHA-384 signature. Almost always a proxy or a truncated download; retry, and check any egress proxy is not rewriting responses. |
Unsupported architecture … for the ionCube Loader. |
Only x86_64 and aarch64 are supported. |
Failed to download the ionCube Loader from … |
No outbound access to downloads.ioncube.com. Open it, or mirror the tarball and re-run with RACKHELM_IONCUBE_URL=https://mirror.example.com/… sudo -E ./install.sh. |
ionCube Loader checksum mismatch; refusing to install it. |
You pinned RACKHELM_IONCUBE_SHA256 and the tarball does not match. ionCube updates this file in place, so a pin can go stale — recompute the hash or drop the pin. |
ionCube did not ship ioncube_loader_lin_8.5.so … |
ionCube has no Loader for that PHP version on this architecture. Re-run against a version they do support, for example RACKHELM_IONCUBE_PHP=8.4 sudo -E ./install.sh. |
ionCube Loader installed but not active for PHP CLI. |
The zend_extension line was written but PHP did not load it. Check that the CLI is reading the configuration directory the installer wrote to, and that no other extension conflicts. Every Composer and Artisan step would fail cryptically otherwise, which is why the installer stops here. |
Tip: The three
RACKHELM_IONCUBE_*variables needsudo -Eto survive into the root environment.
Build and server stage #
| Message | Meaning and fix |
|---|---|
Cannot authenticate to MySQL as an administrator. If a previous run already set a root password, pass it via ~/.my.cnf and retry. |
You are re-running the installer after it already secured MySQL root. The installer tries socket authentication and then Debian’s maintenance account; if neither works, put the root password in ~/.my.cnf. |
nginx configuration test or restart failed. |
Another site is already bound to port 80 or claims the same server_name. Run nginx -t for the specific error. |
Failure in the composer thread |
Usually the ionCube Loader not being active for CLI, or no outbound access to packagist.org. |
Failure in the npm thread |
Out of memory during the Vite build, or no outbound access to the npm registry. Note this thread runs after MySQL has already been reconfigured, so a re-run needs the MySQL note above. |
Migration stage #
| Symptom | Meaning and fix |
|---|---|
Database migration/seeding failed. |
Read /var/log/rackhelm_install_artisan.log. Common causes: wrong remote-database credentials, a database user without permission to create tables, or a database that is not empty. |
| No Admin Panel Credentials block at the end | The seeder only prints credentials the first time it creates the Super Admin. Re-running against an existing database leaves the account — and its existing password — alone. |
Certificate and HTTPS #
Certificate issuance is allowed to fail without aborting the install, because a domain that has not propagated yet is a normal situation. The installer prints:
WARNING: the Let's Encrypt certificate could NOT be issued. Check that
portal.example.com resolves to this server and port 80 is reachable, then retry:
certbot --nginx -d portal.example.com --redirect
Take that seriously. Until a certificate is in place the portal serves plain HTTP, and every login fails with a 419 error because the session cookie is HTTPS-only. Fix DNS and firewalling, run the certbot command, then set APP_URL and ASSET_URL to the https:// address. See Web server, SSL and HTTPS.
Problems after a successful install #
| Symptom | Meaning and fix |
|---|---|
400 Bad Request on every URL, and nothing in storage/logs/laravel.log |
The Host header does not match APP_URL. RackHelm trusts only that host, and the rejection happens before anything is logged. Correct APP_URL — and remember the Company URL setting overrides it once the database is readable. |
| Connections to the server IP hang or return nothing | Expected on Debian and Ubuntu: a catch-all nginx server returns 444 for any other hostname. Use the portal’s own hostname. |
Licence validation error: … on every page |
See Licensing and activation for the failure codes, which are logged to storage/logs/laravel.log prefixed [License]. |
| Orders stay at pending provisioning | The queue worker is down. Check supervisorctl status rackhelm-horizon and storage/logs/horizon.log. |
| No invoices are ever generated | There is no schedule:run cron entry — the installer does not create one — or the seeded schedules are still disabled. See Queue workers, Horizon and the scheduler. |
| Pages render without styling | The Vite build did not complete, or public/build is not readable by the web-server user. Check /var/log/rackhelm_install_npm.log. |
| Uploaded logos and page images 404 | The public/storage symlink is missing. Run php artisan storage:link. |
| Permission-denied errors writing logs or uploads | Ownership drifted. storage and bootstrap/cache must be owned by the web-server user; everything else root:<web user>. |
| No mail is delivered | The installer strips every MAIL_ line from .env. Configure the relay under Platform Settings → Mail Settings. |
Re-running the installer #
The installer is written to survive a second run: it detects an existing database user and forces its password back into step with the newly generated one in .env, it skips the file copy when the archive was extracted straight into the install directory, and it clears stale compiled caches before rebuilding. The one thing it cannot recover on its own is the MySQL root password it set on the first pass — if socket authentication no longer works, put that password into ~/.my.cnf first.
Warning: Re-running against a populated production database re-runs
migrate --seed. Back the database up first. See Backing up and restoring.
What to send to support #
- The exact stage name and message the installer printed.
- The tail of the matching
/var/log/rackhelm_install_*.log, with any passwords removed. - Your distribution and version, and the output of
php -v(which should mention ionCube). - The version shown in the admin sidebar footer, if the portal loads at all.