Installation
Project Super ships as static binaries (superd, super) with no runtime dependencies on Python or a JVM. Building from source requires Rust 1.85+ (stable; edition 2024).
Supported platforms
Super is cross-platform in the sense that the same super.toml and API workflow work wherever you run superd — but how you install depends on your OS:
| Platform | Native binaries | Typical install |
|---|---|---|
| Linux (amd64, arm64) | ✅ GitHub Releases | install.sh (systemd), Docker, or tarball |
| macOS (Intel, Apple Silicon) | ✅ Releases | install.sh (launchd) or tarball |
| FreeBSD (amd64) | ✅ Releases | install.sh (rc.d) or tarball |
| Windows | ❌ Not published | Docker on the host (Docker Desktop or WSL2) |
Note
Windows: there is no native superd.exe release today. Run the official Linux container image locally, or develop on WSL2/Linux/macOS. See the warning under Method 3 for details.
On any supported host, set SUPER_ROOT, place config under conf/super.toml, and use the same CLI/API — whether you extracted a tarball or started a container.
| Stage | Where |
|---|---|
| Get binaries | Method 1 Docker · Method 2 install.sh · Method 3 tarball / source |
| Instance dirs + config | Instance layout and config (also done for you by install.sh) |
Start superd | By hand or OS service |
Method 1: Docker (Recommended)
The official OSS image ships superd and super (API + CLI) on a distroless runtime — no shell, no Python, no package manager. A static busybox binary is included at /usr/local/bin/busybox so the Quick Start demo can run a tiny HTTP server inside the container. Production workloads should use your own app binaries (multi-stage FROM + copy superd, or mount conf/ with stack files pointing at binaries you ship).
Pull and run
The image ships with a default config at /app/super/conf/super.toml (host = "0.0.0.0", port 9002, placeholder auth_secret = "CHANGE-ME-BEFORE-EXPOSE"). Non-loopback bind requires that secret — replace it before publishing beyond the host. Use it for Dashboard login and super --token / super login — see Authentication. Prefer publishing only to loopback on the host (-p 127.0.0.1:9002:9002) unless you intentionally expose the API.
docker pull schiplat/super:latest
docker run --rm -p 127.0.0.1:9002:9002 -p 127.0.0.1:8080:8080 schiplat/super:latestOpen http://127.0.0.1:9002 for the embedded Dashboard and HTTP API. Follow Quick Start — Docker tabs to register the demo busybox httpd program (do not use the Python example inside this image).
Images are published for linux/amd64 and linux/arm64. Docker picks the matching manifest for your host (docker buildx imagetools inspect schiplat/super:latest).
CLI on the host (containerized superd)
The image runs superd in the foreground; you control it over HTTP on port 9002. After -p 127.0.0.1:9002:9002, you do not need a shell inside the container for routine ops.
Option A — install the CLI on the host (recommended):
# From GitHub Releases tarball or install.sh — you only need the `super` binary on PATH.
# Image ships auth_secret = "CHANGE-ME-BEFORE-EXPOSE" — pass it (or export SUPER_TOKEN=…).
export SUPER_TOKEN=CHANGE-ME-BEFORE-EXPOSE
super --server http://127.0.0.1:9002 list
super --server http://127.0.0.1:9002 add --name my-app --autostart /path/to/appIf the host has no local $SUPER_ROOT/run/superd.sock, the CLI already defaults to http://127.0.0.1:9002 — after -p 127.0.0.1:9002:9002, super list works once the binary is on PATH and SUPER_TOKEN / --token matches auth_secret. Use --server when you publish a different host/port, or when a local socket would otherwise take precedence.
Option B — copy super out of the image (no full install):
CID=$(docker create schiplat/super:latest)
docker cp "$CID:/usr/local/bin/super" ./super && docker rm "$CID"
chmod +x ./super
./super --server http://127.0.0.1:9002 --token CHANGE-ME-BEFORE-EXPOSE listOption C — docker exec (quick try; name your container, e.g. docker run --name super …):
docker exec -e SUPER_TOKEN=CHANGE-ME-BEFORE-EXPOSE super /usr/local/bin/super listOption D — REST only: curl -H "Authorization: Bearer CHANGE-ME-BEFORE-EXPOSE" http://127.0.0.1:9002/api/v1/… (no CLI binary; /health needs no Bearer).
Note
Host super will not auto-discover the container’s Unix socket (run/superd.sock lives inside the container). Always pass --server http://127.0.0.1:9002 (or the host/port you published) when superd runs in Docker.
Custom configuration
Mount your own conf/ (and optionally data/ for persistence):
docker run --rm -p 127.0.0.1:9002:9002 \
-v /path/to/conf:/app/super/conf \
-v /path/to/data:/app/super/data \
schiplat/super:latestPlace super.toml under /path/to/conf/. Reference profiles in packaging/docker/conf/:
super.toml— OSS default baked into the image (host = "0.0.0.0"so the container can accept mapped ports; core auth applies — see Authentication). How to structure the file and every supported key: Configuration and Config Reference.super.subscription.example.toml— subscription template (not a runtime config — copy its contents intosuper.toml) with[license].key,auth_secret, and security plugin expectations. Parameter details: Config Reference. Mandatory security plugin +auth_secretat startup: Licensed deployments require security.
Drop stack files into conf/conf.d/* (TOML by default; legacy .json also works) to seed programs on startup.
Non-loopback binds require a non-empty [server].auth_secret (or the security plugin when licensed) — otherwise superd refuses to start. Prefer publishing Docker ports to 127.0.0.1 on the host unless you intentionally expose the API.
If you add licensed plugins, security.so and auth_secret are required for startup — security is included with every subscription. See Licensed deployments require security.
Build from this repository
git clone https://github.com/schiplat/super.git
cd super
docker build -f packaging/docker/Dockerfile -t schiplat/super:latest .Or: make docker. See packaging/docker/README.md for publish notes.
Use as a base image in your stack
FROM ubuntu:22.04
COPY --from=schiplat/super:latest /usr/local/bin/superd /usr/local/bin/superd
COPY --from=schiplat/super:latest /usr/local/bin/super /usr/local/bin/super
COPY conf/ /app/super/conf/
RUN apt-get update && apt-get install -y --no-install-recommends tini \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/superd"]For container signal handling and tini guidance, see Zombie reaping in containers. For how Super compares to Supervisor or shell entrypoints, see vs Supervisor.
Method 2: install.sh (recommended on Linux / macOS / FreeBSD)
One-liner from the latest GitHub Release asset (pinned to the tagged binaries):
curl -fsSL https://github.com/schiplat/super/releases/latest/download/install.sh | shBleeding-edge script from master (may download a different release than the script revision):curl -fsSL https://raw.githubusercontent.com/schiplat/super/master/install.sh | sh
Requirements: POSIX sh, tar, and curl — or on a pristine FreeBSD base system, base fetch alone is enough (fetch -o - <url> | sh); checksums verify with sha256sum, shasum, or the FreeBSD base sha256.
What it does by default:
- Downloads the matching release archive and verifies
SHA256SUMS - Installs
superd+superinto/usr/local/bin(or~/.local/binif not writable) - Creates a minimal instance root:
- System install:
/opt/super - User install:
~/.super - Layout:
conf/super.toml,conf/conf.d/,data/,logs/,run/,plugins/, plusenv.sh
- System install:
- Wires login environment so
SUPER_ROOT(andbinonPATHwhen needed) is set automatically:- Linux (system):
/etc/profile.d/super.sh+SUPER_ROOTin/etc/environment - macOS (system):
/etc/paths.d/super+ hooks in/etc/zprofile(and bash/profile) - User install: marked block in
~/.zprofile/~/.profile(and existing~/.bash_profilewhen present)
- Linux (system):
- Enables and starts an OS service (boot-persistent):
- Linux:
superd.servicevia systemd (enable --now) - macOS:
com.schiplat.superdvia launchd (RunAtLoad+KeepAlive) - FreeBSD:
/usr/local/etc/rc.d/superd+/etc/rc.conf.d/superd(superd_enable=YES);--userusessuperd --daemon
- Linux:
Useful flags:
| Flag | Effect |
|---|---|
--version X.Y.Z | Pin a release |
--prefix DIR | Binary prefix (DIR/bin) |
--root DIR | Instance SUPER_ROOT |
--user / --system | Force per-user or system-wide service |
--no-service | Binaries + instance only (no systemd/launchd/rc.d) |
--no-start | Install/enable service but do not start yet |
--no-init | Skip creating SUPER_ROOT |
--no-sudo | Never elevate |
--base-url URL | Local/CI fake release server (see tools/scripts/install-smoke.sh) |
After install (open a new terminal so login env applies):
super doctor
super add --name demo --autostart sleep 3600
super listIn the same shell as the installer, run source /opt/super/env.sh (or ~/.super/env.sh) once.
Upgrade / reinstall
Re-running install.sh is safe as an upgrade path:
- Overwrites
superd/superbinaries and refreshes the OS unit / plist / rc.d script - Keeps an existing
$SUPER_ROOT/conf/super.toml(does not clobber local edits) - Rewrites
$SUPER_ROOT/env.shand login hooks; restarts the service when start is enabled
Pin with --version X.Y.Z when you need a specific release.
Uninstall (manual)
There is no --uninstall yet. Typical cleanup:
# Linux (system)
sudo systemctl disable --now superd
sudo rm -f /etc/systemd/system/superd.service /etc/profile.d/super.sh
sudo systemctl daemon-reload
# optional: remove SUPER_ROOT= from /etc/environment
# optional: sudo rm -rf /opt/super /usr/local/bin/superd /usr/local/bin/super
# macOS (system)
sudo launchctl bootout system/com.schiplat.superd
sudo rm -f /Library/LaunchDaemons/com.schiplat.superd.plist /etc/paths.d/super
# remove Project Super marker blocks from /etc/zprofile (and bash/profile) if present
# FreeBSD (system)
sudo service superd stop
sudo sysrc -f /etc/rc.conf.d/superd superd_enable=NO
sudo rm -f /usr/local/etc/rc.d/superd /etc/rc.conf.d/superdUser installs: systemctl --user disable --now superd or launchctl bootout gui/$(id -u)/com.schiplat.superd, then remove ~/.super and ~/.local/bin/super{,d} as needed.
Important
install.sh sets SUPER_ROOT for login sessions (see above). Always keep the daemon’s service Environment=SUPER_ROOT=… in sync with $SUPER_ROOT/env.sh. Binaries under /usr/local/bin must not infer the instance root from the executable path — that would incorrectly pick /usr/local.
System install + Unix socket: default socket = "run/superd.sock" is mode 0600 owned by the service user (often root). Non-root CLI either uses sudo -E super …, super --server http://127.0.0.1:9002 … (loopback TCP still listens), or set socket_mode = "0660" and share a group on $SUPER_ROOT/run.
Method 3: GitHub Releases or build from source
Pre-built archives are published on GitHub Releases. Prefer install.sh when you want systemd/launchd/rc.d wired automatically. For a manual extract:
| Archive | Platform |
|---|---|
super-{version}-linux-amd64.tar.gz | Linux x86_64 |
super-{version}-linux-arm64.tar.gz | Linux ARM64 |
super-{version}-macos-amd64.tar.gz | macOS Intel |
super-{version}-macos-arm64.tar.gz | macOS Apple Silicon |
super-{version}-freebsd-amd64.tar.gz | FreeBSD x86_64 |
Each archive contains bin/superd, bin/super, contrib/ (default config + unit templates), and a README. A SHA256SUMS file is attached to every release.
Warning
Pre-built Windows binaries are not published at this time. On Windows hosts, use Docker (Docker Desktop or WSL2) — see Supported platforms. You can also build from source on Linux, macOS, or FreeBSD.
To build locally (requires Rust 1.85+):
git clone https://github.com/schiplat/super.git
cd super
make build
./target/release/superd --help
./target/release/super --versionAfter you have binaries, continue with Instance layout and config, then Start the daemon.
Instance layout and config
Needed for every native install (tarball, make build, or install.sh --no-service). Docker images already ship a layout under /app/super/; install.sh without --no-init creates the same tree under /opt/super or ~/.super.
Directories
Pick a directory you own and export it as SUPER_ROOT. Relative paths in config (logs/, data/, run/…) resolve under this root — do not leave SUPER_ROOT unset when starting from a random cwd (logs and data would land in the wrong place).
export SUPER_ROOT=/opt/super # or ~/super-demo, /tmp/super-dev, …
mkdir -p "$SUPER_ROOT/conf/conf.d" \
"$SUPER_ROOT/data" \
"$SUPER_ROOT/logs" \
"$SUPER_ROOT/run" \
"$SUPER_ROOT/plugins"
# Socket parent must not be group/world-writable (superd refuses to bind).
chmod 755 "$SUPER_ROOT/run" "$SUPER_ROOT/logs" "$SUPER_ROOT/data"| Path | Role |
|---|---|
conf/super.toml | Daemon config (create next) |
conf/conf.d/ | Optional stack files (*.toml) matched by [include].files |
data/ | Snapshot + event DB (snapshot.json, events.db) |
logs/ | Daemon rolling log + child {uuid}.out / .err |
run/ | Unix socket (superd.sock) and optional pidfile |
plugins/ | Licensed plugin libraries (empty in OSS) |
One-shot init without a service: curl …/install.sh | sh -s -- --no-service (or --no-start to install the unit but leave the daemon stopped).
Initialize conf/super.toml
superd reads $SUPER_ROOT/conf/super.toml. Choose one path:
A — Copy the packaged default (recommended after extracting a release tarball):
# From the extracted archive (top-level contrib/):
cp contrib/super.toml.default "$SUPER_ROOT/conf/super.toml"
# Optional sample stack (inactive until you drop the .example suffix):
cp contrib/conf.d/demo.toml.example "$SUPER_ROOT/conf/conf.d/"From a git checkout, the same files live under packaging/contrib/.
B — Write a minimal config by hand (enough for local OSS):
cat > "$SUPER_ROOT/conf/super.toml" <<'EOF'
[server]
host = "127.0.0.1"
port = 9002
# auth_secret = "…" # optional on loopback; required for non-loopback binds
socket = "run/superd.sock"
[storage]
data_file = "data/snapshot.json"
events_file = "data/events.db"
log_dir = "logs"
[include]
files = ["conf/conf.d/*.toml"]
EOFC — Skip the file. If conf/super.toml is missing, superd still starts with built-in defaults (loopback 127.0.0.1:9002). Prefer A or B so bind address, socket, and storage paths are explicit and reviewable.
Do not put programs in super.toml — declare them via conf/conf.d/*.toml, the CLI, or the API (see Configuration and Quick Start). Full key list: Config Reference.
Optional shell helper (same idea as install.sh):
cat > "$SUPER_ROOT/env.sh" <<EOF
export SUPER_ROOT="$SUPER_ROOT"
EOF
# later: source "$SUPER_ROOT/env.sh"Validate before first start:
export SUPER_ROOT=/opt/super
super check # offline config / layout checksStart the daemon
With binaries on PATH (or an absolute path) and SUPER_ROOT set, pick one start mode.
Start by hand
No Docker, no install.sh service wiring, no systemd / launchd / rc.d — the most basic way to run superd.
Foreground (default — leave this terminal open):
superd
# From a source build: ./target/release/superdExpected log lines include Super Core starting... and the listen address. Stop with Ctrl+C, or from another shell with super shutdown. Use foreground for interactive debugging, Docker / Type=simple units, and any supervisor that expects the main process to stay attached.
Detach without an OS service (Unix only):
superd --daemon
# equivalent: [server] daemon = true in super.tomlWrites $SUPER_ROOT/run/superd.pid by default (override with --pidfile / [server] pidfile). Do not combine --daemon with an OS service unit — those must keep superd --foreground. Stop with super shutdown.
Drive it with the CLI (same SUPER_ROOT in another terminal):
export SUPER_ROOT=/opt/super
super doctor
super add --name demo --autostart sleep 3600
super list
super shutdownIf the daemon only exposes TCP (no Unix socket, or you are remote), pass --server http://127.0.0.1:9002.
For a full walkthrough with a demo HTTP program, continue in Quick Start. For Gunicorn + Celery against external Postgres/Redis, see A Django application under Super.
OS service (systemd / launchd / rc.d)
For boot-persistent installs, wire an OS service that keeps superd in the foreground and restarts it on failure. Prefer install.sh when you want this automated. Templates also ship in release contrib/.
Linux — systemd
/etc/systemd/system/superd.service (also in contrib/systemd/superd.service):
[Unit]
Description=Project Super Process Manager
Documentation=https://super.docs.sconts.com/docs/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
# Must stay in the foreground. Do not set [server].daemon = true or pass --daemon.
ExecStart=/usr/local/bin/superd --foreground
Restart=on-failure
RestartSec=2
Environment="SUPER_ROOT=/opt/super"
LimitNOFILE=65536
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now superd
sudo systemctl status superdPer-user units live under ~/.config/systemd/user/ (systemctl --user …). For boot without an interactive login: loginctl enable-linger $USER.
macOS — launchd
macOS has no systemd. Use launchd (what install.sh installs) so superd stays up across reboots and crashes — same idea as a systemd unit: keep the process in the foreground (--foreground), let the OS restart it (KeepAlive).
System-wide: /Library/LaunchDaemons/com.schiplat.superd.plist
Per-user: ~/Library/LaunchAgents/com.schiplat.superd.plist
Templates ship in contrib/launchd/. After copying and editing paths / SUPER_ROOT:
# system
sudo launchctl bootstrap system /Library/LaunchDaemons/com.schiplat.superd.plist
# user
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.schiplat.superd.plistFreeBSD — rc.d
FreeBSD uses rc.d (what install.sh installs under /usr/local/etc/rc.d/superd). The script wraps superd --foreground with daemon(8) (-r restarts on exit). Do not set [server].daemon or pass --daemon when using rc.d.
# enable + paths (install.sh writes /etc/rc.conf.d/superd)
sysrc -f /etc/rc.conf.d/superd superd_enable=YES
sysrc -f /etc/rc.conf.d/superd superd_root=/opt/super
sysrc -f /etc/rc.conf.d/superd superd_bin=/usr/local/bin/superd
service superd start
service superd statusTemplate: contrib/rc.d/superd. Per-user installs (--user) have no rc.d — use superd --daemon instead.
Crash recovery semantics
If superd itself terminates unexpectedly (for example, a fault in a loaded
subscription plugin), the OS service manager restarts it (Restart=on-failure
with RestartSec=2 in the shipped unit; launchd KeepAlive and rc.d
daemon -r behave equivalently). During the restart window managed programs
keep running as orphans but are unmonitored: no health checks, restarts,
hooks, or events fire. After superd comes back it re-adopts the surviving
processes from its persistent store and resumes supervision, so the gap is
typically a few seconds.
Keep superd under a service manager in production for exactly this reason,
and treat a superd restart as a signal to check logs/app.log.* for the
failing component.
Note
Default layout is $SUPER_ROOT/conf/super.toml. Set SUPER_ROOT if your layout differs (see Environment Variables). For no-service starts, see Start by hand.
Next steps
- Getting Started — section overview (Installation + Quick Start)
- Quick Start — first managed demo program (CLI / REST / Docker tabs)
- Configuration —
super.toml, includes, and stacks - A Django application under Super — Gunicorn + Celery against external Postgres/Redis
- Environment Variables —
SUPER_ROOTand related overrides
Was this page helpful? Thanks for your feedback!
Still have questions? Open an issue or browse the source.