Install with Docker
Updated 2026-09-08 · Pharos 0.5.10
The short way: curl -fsSL https://pharos.solutionmax.net/get | sh on a host with Docker (it offers to install Docker if it is missing) writes a compose file and a fresh APP_KEY, pulls the image and brings the two containers up. By hand: Two containers from the same image, ghcr.io/solutionmax/pharos (one tag per release plus :latest, linux/amd64 and linux/arm64): Apache with mod_php serving the app, and a second one
running the scheduler. They share the database and storage volumes.
git clone https://github.com/solutionmax/pharos.git && cd pharos cp .env.docker.example .env docker run --rm php:8.3-cli php -r "echo 'base64:'.base64_encode(random_bytes(32)).PHP_EOL;"
Paste that whole string, including the base64: prefix, into APP_KEY=.
Compose refuses to start without it. Then:
docker compose up -d docker compose exec app php artisan pharos:user [email protected] --name="Your Name"
docker compose up -d pulls the tagged image, or builds it from the checkout when the registry image is not reachable.
Updating is docker compose pull && docker compose up -d. Inside a container Pharos does
not replace its own files: the Updates screen says the install is managed from the host and shows that
command. Pin a release with PHAROS_VERSION=0.5.10 in .env; docker compose up -d --build
builds the same image from the checkout when you would rather not pull it. The installer does the same on its own:
it pulls the image and only builds it from the signed release archive when the registry cannot be reached.
There is no separate migrate step. The entrypoint runs migrations on every container start, clears the caches and rebuilds them, and for SQLite fixes the database directory's ownership.
The scheduler container must stay up. If you scale it to zero, nothing is checked and every component freezes at whatever status it last had — which looks exactly like everything being fine.