Installation
Ruscker is a single binary. Pick the packaging that fits your host.
Debian / Ubuntu (.deb)
The most ShinyProxy-like install: a systemd service on your Docker host. Packages for amd64 and arm64 are attached to every GitHub release.
# amd64
sudo apt install ./ruscker_<version>-1_amd64.deb
# arm64
sudo apt install ./ruscker_<version>-1_arm64.deb
This:
- installs
/usr/bin/ruscker, - creates a
rusckersystem user, - installs a hardened
ruscker.serviceunit and enables + starts it, - drops a minimal config at
/etc/ruscker/application.ymland a secrets file at/etc/ruscker/ruscker.env, - generates a unique admin token on first install and prints it once (there is no default password),
- runs with the admin catalog enabled (
--db /var/lib/ruscker/ruscker.db), so the admin panel works out of the box and a set of showcase apps seeds on first boot.
systemctl status ruscker
curl http://localhost:8080/healthz
sudo grep RUSCKER_ADMIN_TOKEN /etc/ruscker/ruscker.env # your admin token
Log in at /admin with the printed token to manage apps, the landing
page and users — that’s where day-to-day configuration lives (stored
in the catalog DB, not the YAML). application.yml holds deployment
settings; put secrets in /etc/ruscker/ruscker.env. After editing either
file, sudo systemctl restart ruscker.
To actually run the demo apps (and your own containers) enable the Docker
backend: sudo ruscker-enable-docker. See Deploying in
production for nginx + TLS, and
Configuration for what lives where.
Uninstall & reset
Pick the scope you want:
| Goal | Command | What’s left |
|---|---|---|
| Remove the software, keep config + data | sudo apt remove ruscker | /etc/ruscker (config, admin token, keys) and /var/lib/ruscker (catalog DB) — a reinstall resumes where you left off. |
| Remove everything (no trace) | sudo apt purge ruscker | Nothing. Drops the catalog DB and /etc/ruscker — including application.yml and the admin token / master key in ruscker.env. |
| Reset to a brand-new install | sudo apt purge ruscker && sudo apt install ./ruscker_<version>-1_amd64.deb | A pristine box: the default application.yml (no custom title/specs) and a freshly generated admin token, exactly like a first install. |
| Wipe the data only, keep config | stop, remove the DB, start (below) | Config + token unchanged; the catalog is empty, so migrations re-run and the showcase cards re-seed on next boot. |
To wipe just the catalog (a “fresh portal” without uninstalling):
sudo systemctl stop ruscker
sudo rm -f /var/lib/ruscker/ruscker.db # + -wal/-shm if present
sudo systemctl start ruscker
The catalog DB lives in
/var/lib/ruscker; your config and secrets live in/etc/ruscker.purgeclears both; removing the DB clears only the catalog. The portal title comes fromproxy.titleinapplication.yml, so it survives a data-only wipe — only apurge(or editing the file) changes it.
Static musl tarball
For hosts without a package manager, or for quick installs without a systemd unit, download the static musl binary directly. Tarballs for amd64 and arm64 are on the releases page.
tar -xzf ruscker-<version>-linux-amd64.tar.gz
sudo install -m 755 ruscker-<version>-linux-amd64/ruscker /usr/local/bin/ruscker
ruscker --version
The binary has no shared-library dependencies and runs on any glibc-free or glibc Linux system.
Homebrew (macOS / Linux)
For a local install — handy on a macOS workstation for development — use the tap:
brew install strategicprojects/tap/ruscker
ruscker --version
On Linux the formula pulls the static musl binary from the matching
release; on macOS it builds from source (so a Rust toolchain is fetched
as a build dependency). Each release auto-publishes its formula to the
tap, so brew upgrade tracks the latest version.
Ruscker spawns Linux containers, so the
--dockerbackend needs a Linux Docker host. A macOS Homebrew install is meant for running the portal locally and for development, not for hosting app containers.
Docker
docker run --rm -p 8080:8080 \
-v "$PWD/application.yml:/etc/ruscker/application.yml:ro" \
ghcr.io/strategicprojects/ruscker:latest \
serve --config /etc/ruscker/application.yml --bind 0.0.0.0:8080
To let Ruscker spawn app containers (the --docker backend), also
mount the Docker socket and add --docker:
docker run --rm -p 8080:8080 \
-v "$PWD/application.yml:/etc/ruscker/application.yml:ro" \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/strategicprojects/ruscker:latest \
serve --config /etc/ruscker/application.yml --bind 0.0.0.0:8080 --docker
Mounting the Docker socket grants control of the host’s Docker daemon — the same trade-off ShinyProxy carries. Prefer the
.debon the Docker host when you can.
From source
Requires Rust (the pinned toolchain installs automatically via
rust-toolchain.toml):
cargo build --release --bin ruscker
./target/release/ruscker --help
Verifying release artifacts
Every tagged release is signed with cosign
using GitHub Actions OIDC (keyless — no public key to fetch). Each
asset ships a .sha256 plus a .sig + .pem (signing certificate);
the container image is signed by digest.
# Container image
cosign verify ghcr.io/strategicprojects/ruscker:<version> \
--certificate-identity-regexp '^https://github.com/StrategicProjects/ruscker/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
# A downloaded asset (tarball or .deb)
cosign verify-blob ruscker-<version>-linux-amd64.tar.gz \
--signature ruscker-<version>-linux-amd64.tar.gz.sig \
--certificate ruscker-<version>-linux-amd64.tar.gz.pem \
--certificate-identity-regexp '^https://github.com/StrategicProjects/ruscker/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
The exact commands are also printed in each release’s notes.
The serve command
ruscker serve --config <path> [--bind 0.0.0.0:8080] [--docker]
[--db <file>] [--images-dir <dir>] [--log-format json]
[--base-path <prefix>]
| Flag | What it does |
|---|---|
--config | Path to the application.yml. |
--bind | Listen address (defaults to the YAML’s proxy.port). |
--docker | Enable the container backend (spawn app containers). |
--db | SQLite file backing the admin panel. Without it, /admin/* is read-only-ish and the editor returns 503. |
--images-dir | Directory served at /assets/img/. Auto-discovered from the config / ShinyProxy template-path when omitted. |
--log-format | text (default) or json. |
--base-path | Mount the whole portal under a URL prefix (e.g. --base-path /apps). Overrides server.context-path in the YAML. Health probes (/healthz, /readyz) stay at the root. |
Secrets come from the environment: RUSCKER_ADMIN_TOKEN,
RUSCKER_MASTER_KEY, RUSCKER_COOKIE_KEY,
DOCKER_REGISTRY_PASSWORD.