Install on cPanel, DirectAdmin, Plesk or compatible PHP hosting
Updated 2026-09-08 · Pharos 0.5.10
Three ways in, one result: the application lives outside the web root, only its public files are served by the web server, and one cron line runs every minute. Pick the way that fits your host — no SSH, SSH, or by hand. Prefer containers? Skip to Docker. Every path downloads the same signed release: the installer verifies the Ed25519 manifest and the SHA-256 before it unpacks a single file.
A. Without SSH — the web installer (cPanel, DirectAdmin, Plesk)
- Download pharos-install.php and upload it into the document root of the domain you want the status page on — File Manager →
public_html, or the subdomain's folder. - Open
https://status.example.com/pharos-install.php. Unlock it with the private installation key from the file shown on screen, using your hosting File Manager. Keep this key for the administrator form. The next screen checks PHP 8.3+, extensions, writable folders and access to the release server. - Download fetches the release, checks the signed manifest and checksum, unpacks the application into a private
pharos-app-<domain-id>folder — next to the web root, never inside it — and copiespublic/into the document root with anindex.phpthat points at the app. No document-root change is needed, and.envis never reachable from the web. - Configure asks for the site address and the database (SQLite needs nothing from your host; MySQL if you prefer), writes
.envwith a fresh key and runs the migrations. - Cron shows the one line with the right PHP binary for your host. Add it under Cron Jobs (cPanel, DirectAdmin) or Scheduled Tasks (Plesk), press Finish: the installer deletes itself and opens the setup form — name the page, create your administrator.
The installer keeps whatever your panel already put in .htaccess (PHP handler, ini blocks) and adds Pharos's rules underneath, including DirectoryIndex index.php so a placeholder index.html from the panel does not shadow the page. A half-finished install resumes where it stopped; a finished one refuses to run twice.
pharos-app-<domain-id> folder, public/ into the web folder. Now the site address and the database.
B. With SSH — one command
curl -fsSL https://pharos.solutionmax.net/get | sh -s -- --php --url https://status.example.com
The script reads the machine (PHP version and extensions), verifies the manifest and the archive, unpacks into a private pharos-app-<domain-id> folder (change it with --dir), writes .env, migrates, links storage and adds the cron line to your crontab with the PHP binary pinned to the version it found. Where it cannot write the crontab — DirectAdmin's jailed shell, for one — it prints the line for you to add in the panel. Read it first if you like: curl -fsSL https://pharos.solutionmax.net/get | less.
Then point the document root at ~/pharos-app/public. Unlike the web installer, the script does not touch your web folder — this is the one step it leaves to you:
- cPanel: Domains → Manage → Document Root. Over SSH, for a subdomain:
uapi SubDomain changedocroot domain=status.example.com docroot=pharos-app/public. - DirectAdmin: Domain Setup if your host lets you set a document root. Most do not for user accounts; then replace the web folder with a link, which DirectAdmin's Apache follows:
cd ~/domains/status.example.com && mv public_html public_html.orig && ln -s ~/pharos-app/public public_html - Plesk: Hosting Settings → Document root →
pharos-app/public. - Your own server: an nginx or Apache vhost with its root at
/home/you/pharos-app/public, PHP-FPM 8.3, and every unknown path rewritten toindex.php— the.htaccessinpublic/does that on Apache.
Apache and LiteSpeed pick the new root up within a minute. Open the site: the setup form appears. Never set the document root to a private pharos-app-<domain-id> folder itself — that exposes your .env.
Updating is the same command again: the script hands over to Pharos's own updater, which backs the current version up first. The Updates screen in the admin does the same with a button.
Installing a specific version
Both installers take the newest release from /releases/latest.json unless you pin one — to reproduce something, or to walk through an update yourself:
curl -fsSL https://pharos.solutionmax.net/get | sh -s -- --php --url https://status.example.com --version 0.5.10 https://status.example.com/pharos-install.php?version=0.5.10
A pinned install reads pharos-<version>.json, the manifest signed for that exact release; a version that was never published fails cleanly. Each release on the releases page also carries its own pre-pinned copy of the web installer, pharos-install-<version>.php, for when a query string is awkward. Afterwards the Updates screen offers the newest release as usual. Pharos never downgrades on its own: to go back, use Roll back under Updates, restore a verified backup. The get --version option is for new installations and refuses to overwrite an existing PHP install.
C. By hand
If you would rather not run either installer, it is a standard PHP 8.3 application:
git clone https://github.com/solutionmax/pharos.git ~/pharos && cd ~/pharos composer install --no-dev --optimize-autoloader cp .env.example .env && php artisan key:generate touch database/database.sqlite && chmod -R 775 storage bootstrap/cache database php artisan migrate --force && php artisan storage:link php artisan config:cache && php artisan route:cache && php artisan view:cache
Set at least APP_ENV=production, APP_DEBUG=false, APP_URL and DB_CONNECTION=sqlite in .env, point the document root at ~/pharos/public as in B, and add the cron line below. Run php artisan optimize:clear after any .env change.
SQLite needs a writable directory, not just a writable file. It writes its journal next to the database, so permissions on the folder matter as much as on the file itself.
The first browser visit shows the setup form. From the command line instead: php artisan pharos:user [email protected] --name="Your Name" prints a generated password once, updates an existing account rather than failing, and is also how you get back in if you lock yourself out.
The one cron line
Everything time-based hangs off one scheduled command. Both installers give you the exact line; by hand, add a job that runs every minute — cPanel Cron Jobs, DirectAdmin Cron Jobs, Plesk Scheduled Tasks; in the panel's form the five stars go in the time fields and the rest in the command field:
* * * * * cd /home/you/pharos-app && php artisan schedule:run >/dev/null 2>&1
If your host's default php is not 8.3, use the full path to the 8.3 binary — cPanel exposes it as /opt/cpanel/ea-php83/root/usr/bin/php or /opt/alt/php83/usr/bin/php, Plesk as /opt/plesk/php/8.3/bin/php, and DirectAdmin as /usr/local/php83/bin/php. Pharos shows a warning in the admin until it sees the first run; verify by hand with php artisan pharos:check --force.