Sthora
Getting started

Requirements

The machine, the operating system, and the two values you have to decide before running the installer.

The machine

FloorRecommended
RAM2 GB — the installer refuses below this4 GB
Free disk on /20 GB — the installer refuses below this40 GB
CPU1 vCPU2 vCPU

Below 4 GB the installer warns and continues. Builds are the memory spike, and the warning is about builds rather than about the platform sitting idle.

The operating system

  • Ubuntu 22.04, Ubuntu 24.04, or Debian 12. The installer reads /etc/os-release and refuses any other distribution.
  • amd64 or arm64. Images are published for both and for nothing else.
  • Root access for the length of the install.

The installer takes care of everything else — it installs Docker Engine and the Compose v2 plugin if they are missing, creates a 2 GB swapfile if there is no swap, caps the Docker daemon's log files, widens the default address pool, and configures the firewall.

Docker's address pool matters more than it sounds. The default yields roughly 31 bridge networks, and each application gets one. The installer sets a 10.100.0.0/16 base with a /24 size at install time because retrofitting it later means tearing down every network.

What you have to decide

Two values have no safe default, and the installer reads both from the environment:

A hostname that resolves to this machine — STHORA_HOSTNAME. The portal is served on it, and it is what the agent on any second machine dials back to. Create the A record before you install, so the certificate can be issued on the first attempt.

An email address for the certificate authoritySTHORA_ACME_EMAIL. Let's Encrypt sends expiry warnings there and refuses addresses on reserved domains, so ops@example.com will not do.

Everything else the installer generates itself.

Optional, and decided later

A wildcard base domainSTHORA_BASE_DOMAIN. Set it and every application also answers on <slug>.<baseDomain> with no DNS step per application.
An SMTP relayAlerts and password resets go out over it. Without one the platform still runs: sends are skipped and logged, and alerts stay in-app and on webhooks.
A GitHub AppOptional. Deploy keys work against every host with nothing registered anywhere; an App adds a repository picker and deployment status on the commit.

Ports

Inbound 22, 80, and 443 — the installer configures ufw to allow those three and deny everything else. Port 80 is not optional even if you only serve HTTPS: the ACME HTTP-01 challenge needs it.

Docker publishes ports by writing iptables rules that bypass ufw's chains. Never start a container by hand with -p on this box — the firewall will report a port as closed while it is open. Applications deployed through the platform publish nothing.

On this page