Installation
The supported path is the released Docker installer: one command installs
Docker if needed, downloads the compose stack, and writes a fully configured
.env with generated secrets. It does not start the stack.
Prerequisites
Section titled “Prerequisites”The full host baseline is on requirements. In short:
- A supported Linux host: Ubuntu/Debian, RHEL/CentOS/Rocky/Alma, Fedora, Arch, Alpine, or openSUSE. RHEL 10 and Fedora 41+ ship dnf5 and the installer detects it; RHEL 8/9 still use dnf4.
curl,tar, andopenssl(the installer stops if any is missing).- Docker with the Compose v2 plugin (or Podman with
podman compose), or permission for the installer to install Docker for you. - Root access — the one-liner below runs the installer through
sudo bash. - If the host runs
firewalldorufw, the panel port must be open — the installer checks it and prints the command.
Install
Section titled “Install”On the panel host, from a root shell:
curl -fsSL https://github.com/catalystctl/catalyst/releases/latest/download/install.sh | sudo bashThe installer reads its prompts from /dev/tty, so the piped form stays
interactive. It checks the container runtime and Compose, offers to install
Docker when missing, warns when a port it needs is already in use or disk space
is low, then prompts for the panel URL and panel name. It generates every
required secret (POSTGRES_PASSWORD, BETTER_AUTH_SECRET, REDIS_PASSWORD,
API_KEY_SECRET, BACKUP_CREDENTIALS_ENCRYPTION_KEY) and writes .env with
chmod 600.
On firewalld and ufw hosts it also reports whether the panel port
(FRONTEND_PORT, 8080 by default) is allowed and prints the one-line command
to allow it — advisory only, it never changes the host firewall. If you accept
the HTTPS offer it writes DOMAIN and ACME_EMAIL, switches PUBLIC_URL to
https://<domain> and sets NODE_ENV=production.
To pin a specific release instead of tracking the newest one, swap latest for
a tag (this pins the installer script; the stack files still come from main
unless you also set INSTALL_VERSION):
curl -fsSL https://github.com/catalystctl/catalyst/releases/download/v1.85.0/install.sh | sudo bashVerify the download (recommended for production)
Section titled “Verify the download (recommended for production)”Every release publishes install.sh plus an install.sh.sha256. Download both,
check the checksum, then run the file:
VERSION=v1.85.0 # the release you wantcurl -fsSL -o install.sh "https://github.com/catalystctl/catalyst/releases/download/${VERSION}/install.sh"curl -fsSL -o install.sh.sha256 "https://github.com/catalystctl/catalyst/releases/download/${VERSION}/install.sh.sha256"sha256sum -c install.sh.sha256 && sudo bash install.shPassing INSTALL_SHA256=<hash> makes the script verify itself while it runs (the
raw hex or a whole .sha256 line both work); a mismatch aborts before anything
happens. The self-check hashes the script file, so it does not apply to the piped
one-liner above.
Options
Section titled “Options”Run --help for the full list. Useful flags:
-y,--yes,--non-interactive— accept defaults / use environment overrides without prompting.--set KEY=VALUE— set any.envvariable (repeatable). Applied on top of the prompts, so it also overrides the environment. Secret-looking values are never echoed.--env-file FILE— readKEY=VALUEoverrides from a file, applied before--set(a later--setwins).--dry-run— show what would happen without changing anything.--reconfigure— re-run the.envprompts (existing secrets are preserved so they stay in sync with already-initialized volumes).--update— refresh the compose stack files in./catalyst-docker, keeping.env.--uninstall— remove the stack (data volumes are kept unlessREMOVE_VOLUMES=1is set with-y).
Environment overrides (used with -y, or as prompt defaults):
PUBLIC_URL,APP_NAME— pre-answer the prompts.REMOVE_VOLUMES=1— with--uninstall -y, also delete compose volumes.INSTALL_VERSION— git ref for the stack files. Defaults tomain; a release tag such asv1.85.0pinscatalyst-docker/to that release so a verified installer from release X installs stack X.INSTALL_SHA256— expected checksum ofinstall.shitself (see above).
Example — non-interactive, pinned stack files, custom port and timezone:
INSTALL_VERSION=v1.85.0 bash install.sh -y \ --set PUBLIC_URL=https://panel.example.com \ --set FRONTEND_PORT=0.0.0.0:8081 \ --set TZ=Europe/BerlinThe installer also records the absolute path of the compose directory in
CATALYST_COMPOSE_DIR (bind-mounted at the same path into the backend), which
is what lets the in-panel updater run docker compose — see
updating.
Start the stack
Section titled “Start the stack”The installer configures the stack but does not start it. Review the generated
.env, then bring it up:
cd catalyst-dockernano .env # optional — check everything the installer wrotedocker compose up -dIf you answered the HTTPS offer during install (so PUBLIC_URL is https://…),
start the Caddy overlay instead — it issues the certificate and needs ports
80/443 reachable:
cd catalyst-dockerdocker compose -f docker-compose.yml -f docker-compose.caddy.yml up -dCheck the containers are up with docker ps, then open the panel URL in a
browser.
Finish setup in the browser
Section titled “Finish setup in the browser”Opening the panel URL shows the setup wizard — panel name, admin account, and appearance (first-time setup). The wizard creates the first account with the Administrator role and marks it verified; there is no separate “first user becomes admin” step.
After installing
Section titled “After installing”- Configure TLS and networking.
- Install a node — the panel alone runs no games.
- Update safely when new releases arrive.
catalyst-docker/diagnose.shcollects a redacted support bundle;catalyst-docker/update.shrefreshes the stack files later.
Troubleshooting
Section titled “Troubleshooting”- Installer fails early: re-run with
--dry-runto see the planned steps, and check Docker/Compose are present and your user can reach the Docker socket. - Port warnings during install: something is already listening on a port the
stack wants — stop that service or set the matching
*_PORTvariable (for example--set FRONTEND_PORT=0.0.0.0:8081). - Panel unreachable from another machine but fine on the host: the host firewall
is blocking the panel port. Run the
firewall-cmdorufwcommand the installer printed. - Panel 500s on first login: the database migrations run at container startup —
wait a minute and check container logs (
docker compose logs backend). - More: panel issues.
