Install with Docker
The quick start writes everything on this page for you. Read Requirements first. The install pulls published images (about 20 GB on a machine that runs the agent) and compiles nothing. On Unraid, follow Unraid instead.
This page is rootful Docker (supported): Docker runs as root. To run Quasar as an ordinary account instead, follow Install rootless (experimental). Status per platform: Container engines.
What gets installed
Section titled “What gets installed”You declare one container per machine: the seed. The seed keeps the machine’s
recovery actor running. The recovery actor creates and updates the other
services, and generates and stores the machine’s secrets. There is no compose file
and no .env of secrets.
| Machine | What the recovery actor creates |
|---|---|
| Combined host | Postgres, the control plane, the node agent |
| Control-only host | Postgres and the control plane (no GPU needed) |
| GPU host | The node agent |
The containers are named quasar-recovery, quasar-postgres,
quasar-control-plane and quasar-node-agent. A stack redeploy only touches the
seed. Run one installation per container engine.
What the recovery actor will and will not do
Section titled “What the recovery actor will and will not do”It holds the Docker socket. Its limits:
- It runs images only by digest, and pulls only from the allowed registry namespaces
(
QUASAR_UPDATER_ALLOWED_NAMESPACES, the project’s own by default). See Release signatures. - It acts only on containers it created. A look-alike it did not create, such as a leftover Compose stack, is an owner conflict: it is left alone, updates to that machine are blocked, and the console shows it on the host’s Services on this machine card.
- It never touches your game containers or anything else.
- It keeps the old container stopped until the new one verifies, so a failed update can be rolled back.
Prepare the host
Section titled “Prepare the host”Once, from an account with sudo. The quick start shows the same commands.
sudo systemctl enable --now dockerNVIDIA: complete NVIDIA setup for rootful Docker before deploying. It includes runtime configuration and any required SELinux policy.
Check it worked: systemctl is-enabled docker says enabled on systemd hosts.
Optional: console mode needs the console rules from Device rules, and the UDP send buffer makes streams smoother.
Before you start
Section titled “Before you start”Create the home root on persistent storage on any machine that runs games. It holds saves and installed games. The template root sits beside it:
sudo install -d -m 0755 -o 1000 -g 1000 /var/lib/quasar/homes /var/lib/quasar/templatesUse the owner that suits your host.
Install the first machine
Section titled “Install the first machine”The first machine runs the control plane. A combined host also runs a node agent, so one machine with a GPU is a complete install.
docker run -d --name quasar-seed --restart unless-stopped --pull always \ --security-opt label=disable \ -v /var/run/docker.sock:/var/run/docker.sock \ -v quasar-machine:/var/lib/quasar-machine:ro \ -e QUASAR_ROLE=combined \ -e QUASAR_PUBLIC_HOST=192.168.1.50 \ -e QUASAR_HOME_ROOT=/var/lib/quasar/homes \ -e QUASAR_TEMPLATE_ROOT=/var/lib/quasar/templates \ -e QUASAR_CONTROL_PLANE_IMAGE=ghcr.io/accreleus/quasar/quasar-control-plane:latest \ -e QUASAR_AGENT_IMAGE=ghcr.io/accreleus/quasar/quasar-node-agent:latest \ ghcr.io/accreleus/quasar/quasar-recovery seedservices: quasar-seed: container_name: quasar-seed image: "ghcr.io/accreleus/quasar/quasar-recovery:latest" pull_policy: always command: seed restart: unless-stopped security_opt: [label=disable] environment: QUASAR_ROLE: "combined" QUASAR_PUBLIC_HOST: "192.168.1.50" QUASAR_HOME_ROOT: "/var/lib/quasar/homes" QUASAR_TEMPLATE_ROOT: "/var/lib/quasar/templates" QUASAR_CONTROL_PLANE_IMAGE: "ghcr.io/accreleus/quasar/quasar-control-plane:latest" QUASAR_AGENT_IMAGE: "ghcr.io/accreleus/quasar/quasar-node-agent:latest" volumes: - /var/run/docker.sock:/var/run/docker.sock - quasar-machine:/var/lib/quasar-machine:rovolumes: quasar-machine: name: quasar-machine # required: not <project>_quasar-machineQUASAR_PUBLIC_HOST(set it for LAN access): the name or LAN address you type into the browser. The certificate names it. Extra names go inQUASAR_TLS_HOSTS, comma-separated.- Ports: 8443 (console) and 8080 (agents and
/health). Change withQUASAR_TLS_PORTandQUASAR_HTTP_PORT. - Behind a reverse proxy: add
QUASAR_TRUSTED_PROXIES. See Behind a reverse proxy. - Postgres:
postgres:16-alpine, pinned by the recovery actor.QUASAR_POSTGRES_IMAGEnames another (a tag is pinned at install). Quasar never updates it.
You don’t set a database password, secret key, enrollment string or admin account. The recovery actor generates the secrets, and you claim the instance in the browser: see First run and checks.
Control-only machine: set QUASAR_ROLE=control-only. It needs no GPU, no home
root and no GPU preparation. QUASAR_AGENT_IMAGE is optional: if set, Add host
installs it on new GPU hosts when no release names one. Set QUASAR_HOME_ROOT only
if every GPU host will use that path.
Your own Postgres
Section titled “Your own Postgres”Add the database settings to the seed’s environment. Keep the password in the
stack’s .env:
QUASAR_DATABASE_HOST: "db.example.internal" QUASAR_DATABASE_PORT: "5432" # default 5432 QUASAR_DATABASE_USER: "quasar" # default quasar QUASAR_DATABASE_NAME: "quasar" # default quasar QUASAR_DATABASE_SSLMODE: "require" QUASAR_DATABASE_PASSWORD: "${QUASAR_DATABASE_PASSWORD}"# the stack's .envQUASAR_DATABASE_PASSWORD=<your database password>With docker run, export QUASAR_DATABASE_PASSWORD and pass
-e QUASAR_DATABASE_PASSWORD with no value, to keep it off the command line.
- Set
QUASAR_DATABASE_SSLMODEfor a remote database:require, orverify-full. The default,disable, sends the password in clear text. - The password is copied into the recovery actor’s volume at first install. You can then remove it from the stack.
- Quasar never creates, backs up, restores or upgrades your database. Keep your own backups; the console asks you to confirm one before a migrating update.
Add a GPU host
Section titled “Add a GPU host”Use Add host in Admin ▸ Fleet ▸ Hosts: see Add a GPU host. To start the seed yourself instead, take the enrollment string from the same dialog under Show the enrollment string. It works once and expires after an hour by default (up to 30 days).
docker run -d --name quasar-seed --restart unless-stopped --pull always \ --security-opt label=disable \ -v /var/run/docker.sock:/var/run/docker.sock \ -v quasar-machine:/var/lib/quasar-machine:ro \ -e QUASAR_ROLE=gpu \ -e QUASAR_ENROLLMENT='qenr1.…' \ -e QUASAR_HOME_ROOT=/var/lib/quasar/homes \ -e QUASAR_TEMPLATE_ROOT=/var/lib/quasar/templates \ -e QUASAR_AGENT_IMAGE=ghcr.io/accreleus/quasar/quasar-node-agent:latest \ ghcr.io/accreleus/quasar/quasar-recovery seedservices: quasar-seed: container_name: quasar-seed image: "ghcr.io/accreleus/quasar/quasar-recovery:latest" pull_policy: always command: seed restart: unless-stopped security_opt: [label=disable] environment: QUASAR_ROLE: "gpu" QUASAR_ENROLLMENT: "qenr1.…" # single use; may be deleted once enrolled QUASAR_HOME_ROOT: "/var/lib/quasar/homes" QUASAR_TEMPLATE_ROOT: "/var/lib/quasar/templates" QUASAR_AGENT_IMAGE: "ghcr.io/accreleus/quasar/quasar-node-agent:latest" volumes: - /var/run/docker.sock:/var/run/docker.sock - quasar-machine:/var/lib/quasar-machine:rovolumes: quasar-machine: name: quasar-machine # required: not <project>_quasar-machineOn every machine:
- Images. Name the
:latesttags as shown. The seed pulls them once, pins each to its digest, and records only the digests; if a pull fails it creates nothing and tries again. A moved tag never changes an installed machine, and redeploying the seed does not update it: updates are the console’s Releases page. You may also giverepository@sha256:<digest>to install an exact build. - Both mounts. The engine socket, and the
quasar-machinevolume read-only. In a stack, keep thename: quasar-machineline, or the seed refuses to install (seed-self-invalid). label=disableis required on SELinux and harmless elsewhere.QUASAR_ROLEdefaults togpu.QUASAR_NODE_NAMEdefaults to the host name, and must match a name bound into the enrollment string.- Inputs are read once, on a clean machine. After that you can delete the enrollment string from the stack. It enrolls nothing after first use.
- Host preparation is yours when you start the seed yourself: see Prepare the host. The host’s readiness card lists anything missing.
All inputs: environment reference.
Check it came up
Section titled “Check it came up”docker exec quasar-seed quasar-recovery statusdocker exec quasar-recovery quasar-recovery statusdocker ps --filter label=io.quasar.installation # the seed is not listedOn the first machine:
curl http://localhost:8080/healthYou want {"status":"ok","db":"ok"}. Then open https://<QUASAR_PUBLIC_HOST>:8443
in Chrome, accept the self-signed certificate once, and continue with First run
and checks.
A GPU host appears under Admin ▸ Fleet ▸ Hosts within seconds. The first machine appears under Admin ▸ Fleet ▸ Releases ▸ Installed as This machine.
An install that did not complete
Section titled “An install that did not complete”A refused install writes nothing durable. Fix the stack or docker run line (the
seed’s log names the bad variable) and start the seed again. If the recovery actor
was already created, fix the seed’s inputs, then:
docker restart quasar-recoverySee Install and startup problems.
Keep the quasar-machine volume
Section titled “Keep the quasar-machine volume”Never delete it. It holds the machine’s generated secrets, the update history, the seed’s state and, with Quasar’s own database, the pre-update dumps. The recovery actor needs it while the control plane is down. For the database, use backups.
Removing or redeploying the seed
Section titled “Removing or redeploying the seed”Removing or redeploying the seed never stops Quasar. But without a seed, a deleted recovery actor cannot be re-created. The console warns on the host’s Services on this machine card. Start the seed again to clear it.
To stop Quasar without removing anything, stop its containers, agent first (then the control plane and Postgres on the first machine):
docker stop quasar-node-agentdocker start brings each back. To remove Quasar, use Remove host in the console
or the recovery image’s uninstall: see Uninstalling.
Updating and changing settings
Section titled “Updating and changing settings”Updates come only from Admin ▸ Fleet ▸ Releases. A failed control-plane update rolls back automatically. See Updating Quasar.
Change install-time settings with reconfigure:
docker exec -it quasar-recovery quasar-recovery reconfigure --dry-run QUASAR_HOME_ROOT=/mnt/homesdocker exec -it quasar-recovery quasar-recovery reconfigure --yes QUASAR_HOME_ROOT=/mnt/homesIt re-creates the affected services with the new settings and rolls back if they
don’t verify. Run --dry-run first: re-creating the agent ends that host’s sessions,
and a new HTTPS port disconnects GPU hosts until you add them again.
The database and the node name can’t be changed this way. To change them, back up, uninstall, install again with the new settings, and restore.
Cover artwork
Section titled “Cover artwork”Set the SteamGridDB key in Admin ▸ Library ▸ Sources, SteamGridDB row. A fresh install has none, so tiles show a gradient until you add it.
Application memory and ownership
Section titled “Application memory and ownership”Application containers get 1 GiB of shared memory (QUASAR_APP_SHM_SIZE,
not configurable in this release).
QUASAR_APP_PUID and QUASAR_APP_PGID set who owns game and save data. They are
seed inputs, and reconfigure changes them on a GPU host.
| Port | Input | Purpose |
|---|---|---|
| 8443 | QUASAR_TLS_PORT |
HTTPS web app and API. |
| 8080 | QUASAR_HTTP_PORT |
Agent enrollment and /health. Browser routes redirect to HTTPS. |
For Caddy or an existing ingress, see Behind a reverse proxy.
Building from source
Section titled “Building from source”For contributors only: see Set up a checkout. A source-built machine has no recovery actor and is never offered updates.
Coming from a Compose install
Section titled “Coming from a Compose install”A Compose install keeps running but is not offered new releases. To move to an owned install with your data, see Move a Compose install. To stay, see Legacy Compose installs.