Skip to content

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.

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.

Once, from an account with sudo. The quick start shows the same commands.

Terminal window
sudo systemctl enable --now docker

NVIDIA: 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.

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:

Terminal window
sudo install -d -m 0755 -o 1000 -g 1000 /var/lib/quasar/homes /var/lib/quasar/templates

Use the owner that suits your host.

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.

Terminal window
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 seed
  • QUASAR_PUBLIC_HOST (set it for LAN access): the name or LAN address you type into the browser. The certificate names it. Extra names go in QUASAR_TLS_HOSTS, comma-separated.
  • Ports: 8443 (console) and 8080 (agents and /health). Change with QUASAR_TLS_PORT and QUASAR_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_IMAGE names 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.

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}"
Terminal window
# the stack's .env
QUASAR_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_SSLMODE for a remote database: require, or verify-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.

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).

Terminal window
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 seed

On every machine:

  • Images. Name the :latest tags 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 give repository@sha256:<digest> to install an exact build.
  • Both mounts. The engine socket, and the quasar-machine volume read-only. In a stack, keep the name: quasar-machine line, or the seed refuses to install (seed-self-invalid).
  • label=disable is required on SELinux and harmless elsewhere.
  • QUASAR_ROLE defaults to gpu. QUASAR_NODE_NAME defaults 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.

Terminal window
docker exec quasar-seed quasar-recovery status
docker exec quasar-recovery quasar-recovery status
docker ps --filter label=io.quasar.installation # the seed is not listed

On the first machine:

Terminal window
curl http://localhost:8080/health

You 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.

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:

Terminal window
docker restart quasar-recovery

See Install and startup problems.

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 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):

Terminal window
docker stop quasar-node-agent

docker start brings each back. To remove Quasar, use Remove host in the console or the recovery image’s uninstall: see Uninstalling.

Updates come only from Admin ▸ Fleet ▸ Releases. A failed control-plane update rolls back automatically. See Updating Quasar.

Change install-time settings with reconfigure:

Terminal window
docker exec -it quasar-recovery quasar-recovery reconfigure --dry-run QUASAR_HOME_ROOT=/mnt/homes
docker exec -it quasar-recovery quasar-recovery reconfigure --yes QUASAR_HOME_ROOT=/mnt/homes

It 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.

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 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.

For contributors only: see Set up a checkout. A source-built machine has no recovery actor and is never offered updates.

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.