Installing Levelrail
Levelrail ships as two static Go binaries (levelrail, the control plane, and levelrail-agent, the node agent) plus a CLI (levelrail-cli). This page covers every supported way to get the control plane running on a real Linux host, how to verify it worked, and how to upgrade or remove it afterward.
Option 1: install.sh (recommended)
curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh | sudo shThis is the same script linked from the root README. It handles the full setup automatically:
- Downloads the right
linux/amd64orlinux/arm64binary from the latest GitHub release - Verifies the checksum
- Installs Docker via
get.docker.comif missing - Writes a
levelrail.servicesystemd unit - Starts the service
- Waits up to 60 seconds for the control plane to answer
GET /api/v1/brand
Requires curl, systemd, and root access.
install.sh reads these environment variables, all optional:
| Variable | Default | What it does |
|---|---|---|
LEVELRAIL_VERSION | latest release | Pin a specific release tag instead of resolving the newest one |
LEVELRAIL_INSTALL_DIR | /usr/local/bin | Where the levelrail binary is installed |
LEVELRAIL_DATA_DIR | /var/lib/levelrail-data | Control plane data directory (SQLite database, generated brand.yaml) |
LEVELRAIL_CONFIGURE_UFW | unset (off) | Set to 1 to have the script configure ufw: allow SSH, then 80/443, then enable it if it wasn't already active. Off by default, the script never touches your firewall otherwise. |
Examples:
# Pin a specific release
curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh \
| sudo LEVELRAIL_VERSION=v0.1.0 sh
# Install the binary somewhere other than /usr/local/bin
curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh \
| sudo LEVELRAIL_INSTALL_DIR=/opt/levelrail/bin sh
# Use a custom data directory
curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh \
| sudo LEVELRAIL_DATA_DIR=/data/levelrail sh
# Let the script open 80/443 (and SSH, if not already allowed) via ufw
curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh \
| sudo LEVELRAIL_CONFIGURE_UFW=1 shMultiple overrides combine normally:
sudo LEVELRAIL_VERSION=v0.1.0 LEVELRAIL_DATA_DIR=/data/levelrail shOption 2: Docker
Already running everything else as containers? See docs/docker.md for docker run and docker-compose.yml examples.
Images available:
ghcr.io/glincker/levelrail(control plane)ghcr.io/glincker/levelrail-agent(node agent)
Both are published for linux/amd64 and linux/arm64 on every tagged release.
TIP
install.sh remains the recommended path for a real single-node deployment since it also provisions Docker and a systemd unit for you. The Docker image is for operators who want Levelrail to fit into an existing container-only setup.
Option 3: build from source
See docs/getting-started.md for the go build commands. This is the path for contributors and anyone who wants to run an unreleased commit rather than a tagged version.
Verifying the install
install.sh already fails loudly if the control plane doesn't come up healthy within 60 seconds. You can re-check the installation at any time:
Quick checks (unauthenticated):
# Health check the control plane responds
curl -fsS http://127.0.0.1:8080/api/v1/brand
# Check systemd service status
systemctl status levelrail
# View logs in real time
journalctl -u levelrail -fAuthenticated checks (after initial setup):
Once you've created an admin account and minted an API token (see docs/getting-started.md), you can use levelrail-cli for deeper validation:
levelrail-cli version # compare running vs. latest published release
levelrail-cli status # check Docker reachability and system configBoth commands talk to the control plane's API (GET /api/v1/updates and GET /api/v1/system/status), confirming it is reachable and authenticating correctly.
Upgrading
If you used install.sh:
Re-run the same one-liner. It's safe to re-run: it overwrites the binary and unit file, then restarts the service.
curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh | sudo shTo pin a specific release instead of the latest:
curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh \
| sudo LEVELRAIL_VERSION=v0.1.0 shIf you used Docker:
Pull the new tag and recreate the container:
docker pull ghcr.io/glincker/levelrail:latest
docker compose up -dOr if using docker run:
docker rm -f levelrail
# Re-run the docker run command from docs/docker.mdThe named volume holding /var/lib/levelrail-data persists across recreation.
Uninstalling
There is no uninstall script today.
If you used install.sh:
sudo systemctl stop levelrail
sudo systemctl disable levelrail
sudo rm /etc/systemd/system/levelrail.service
sudo systemctl daemon-reload
sudo rm "$(command -v levelrail)" # or your LEVELRAIL_INSTALL_DIR path
sudo rm -rf /var/lib/levelrail-data # or your LEVELRAIL_DATA_DIR pathWARNING
Removing /var/lib/levelrail-data deletes all app and deploy state.
This does not touch Docker itself or any containers, images, or volumes Levelrail created for your deployed apps. Remove those separately if needed.
If you used Docker:
docker rm -f levelrail levelrail-agent
docker volume rm levelrail-data