Skip to content

v0.8.7

Choose a tag to compare

@glinr-bot glinr-bot released this 29 Oct 14:58
9d8d46e

Levelrail v0.8.7 is a self-hosted deployment platform: one control plane for Docker apps, databases, TLS, logs, metrics and rollback across your own servers. A lightweight alternative to Coolify, Dokploy and Kubernetes for small teams.

Highlights

  • compose: corpus test and warnings for compose keys that are ignored (e09ec38) by @thegdsks
  • templates: mark smoke-tested templates as verified in API and CLI (3f503bb) by @thegdsks
  • mcp: failed deploy waits return a compact redacted diagnosis (c43dc05) by @thegdsks

What's changed

Features

  • compose: corpus test and warnings for compose keys that are ignored (e09ec38) by @thegdsks
  • templates: mark smoke-tested templates as verified in API and CLI (3f503bb) by @thegdsks
  • mcp: failed deploy waits return a compact redacted diagnosis (c43dc05) by @thegdsks
  • mcp: deploy_app can wait for the outcome and diagnose failures (9304dfe) by @thegdsks
  • cli: deploy-compose warns about ignored compose keys (0d180a1) by @thegdsks
  • compose: apply mem_limit, cpus and deploy resource limits (4d98673) by @thegdsks
  • templates: Verified badge and Verified only filter in the dashboard (8eecf51) by @thegdsks
  • templates: open a template deploy page from /templates?deploy= (eb3fbe3) by @thegdsks
  • apps deploy-compose prints the API's compose warnings (4c15047) by @thegdsks
  • prcmd: audit every refused pull request comment command (deeaa90) by @thegdsks
  • prcmd: ignore oversized pull request comments before parsing (d5199bc) by @thegdsks
  • prcmd: add /levelrail help for users with write access (cefec8f) by @thegdsks
  • web: say a first deploy can take up to two minutes (7d782a6) by @thegdsks
  • cli: up stops when the remote branch lacks your commit (32c8a07) by @thegdsks
  • cli: up waits for a healthy first deploy (3574b29) by @thegdsks
  • catalog: add RSSHub template (16126b1) by @thegdsks
  • web: one next action on the empty dashboard (1df51cf) by @thegdsks
  • templates: add ArchiveBox web archiver template (b7a24fb) by @thegdsks
  • templates: add Crawl4AI crawler API template (0291441) by @thegdsks
  • dashboard: give the available update its own strip (739a26a) by @thegdsks
  • templates: add Backrest restic backup web UI (0a8e17c) by @thegdsks
  • shell: link the sidebar version to update settings (9e5d3f4) by @thegdsks
  • templates: add Open Notebook research template (da57500) by @thegdsks
  • catalog: add Headscale and Authelia templates (77c1fb4) by @thegdsks
  • web: open the first app by its direct address when HTTPS is off (71835d6) by @thegdsks
  • compose: accept UDP ports and store them per service (19b4b92) by @thegdsks
  • reconcile: publish UDP ports directly on the host (6ebe08a) by @thegdsks
  • api: show UDP ports and refuse conflicting compose deploys (adcbc1e) by @thegdsks
  • cli: decode published ports on app and compose deploy responses (a630c99) by @thegdsks
  • web: type published ports on apps and compose services (6e46267) by @thegdsks
  • cli: show published ports as 53/udp in apps and compose output (cce31d8) by @thegdsks
  • api: app urls report a plain-http link when the ingress routes one (a0e426f) by @thegdsks
  • web: show UDP and TCP published ports on the app network panel (5a8c21b) by @thegdsks
  • cli: explain published port refusals with a next step (786c18d) by @thegdsks
  • firewall: list published UDP ports in the host firewall view (5a09739) by @thegdsks
  • cli: apps create --file sends published_ports (70d8b2e) by @thegdsks
  • web: explain published port deploy errors with a fix hint (1be4c72) by @thegdsks
  • compose: refuse a UDP port another host process already binds (259aafb) by @thegdsks
  • compose: apply shm_size to /dev/shm with drift recreate (29eb24c) by @thegdsks
  • cli: explain a host port already in use (14b49fa) by @thegdsks
  • web: edit UDP and TCP published ports in the app port editor (3690f0c) by @thegdsks
  • web: show UDP rows in the host firewall card and port-in-use hint (4a65c01) by @thegdsks
  • catalog: add Radicale template (711c5bf) by @thegdsks
  • catalog: add RustDesk server template (5350b08) by @thegdsks
  • catalog: expose an optional template description in the API (6a77b77) by @thegdsks
  • catalog: add setup notes to RustDesk, Mosquitto and two more templates (a7ae492) by @thegdsks
  • cli: show template setup notes in templates get (5a80fd9) by @thegdsks
  • web: show template setup notes in the detail page and deploy dialog (d43509b) by @thegdsks
  • compose: record an explicit restart no or on-failure policy (48c56ad) by @thegdsks
  • web: show the approving state on deploy approvals (249cafd) by @thegdsks
  • templates: show address, logins and notes after a template deploy (8ad6963) by @thegdsks
  • ui: confirm app Restart and Stop before running (b759fd8) by @thegdsks
  • api: verify GitLab and CircleCI OIDC identity tokens (1c6b267) by @thegdsks
  • iac: stacks declare published ports and run-to-completion restart (01ae110) by @thegdsks
  • web: first app always shows an openable address and failure reason (6c4ffb2) by @thegdsks
  • ci: trust GitLab and CircleCI pipelines to deploy with OIDC (1b8afb4) by @thegdsks
  • ui: follow Restart and Stop until the app is really back (f130bfa) by @thegdsks
  • api: report deploy outcome and reason on every deploy response (cf90975) by @thegdsks
  • templates: keep access details on the app page and in the wizard (847136b) by @thegdsks
  • ci: trust GitLab and CircleCI pipelines to plan and apply stacks (cf6ec5e) by @thegdsks
  • cli: add provider-neutral apps ci token and trust commands (3135618) by @thegdsks
  • web: choose GitHub, GitLab or CircleCI when trusting a CI pipeline (81d5352) by @thegdsks
  • apps: show template setup notes in Access details for any template app (c2c45db) by @thegdsks
  • mcp: deploy_template installs a catalog template from an agent (0086a04) by @thegdsks
  • app status reports the deploy outcome and reason (aa32fc4) by @thegdsks
  • CLI status and wait print the server's deploy outcome reason (fe916d4) by @thegdsks
  • dashboard hero uses the server deploy outcome (f779291) by @thegdsks
  • web: stacks page gets palette search keywords and preview (548726e) by @thegdsks
  • compose: health probes run from outside the container (03abded) by @thegdsks
  • files: inline config files written into the container before start (816518c) by @thegdsks
  • mcp: stack tools and graduation tests for secrets and lease contention (47a91cb) by @thegdsks
  • domains: guided four-step domain setup stepper (d73482e) by @thegdsks
  • files: files API and compose inline configs (e444234) by @thegdsks
  • deploy: wait for CI checks before a push deploy (0fe52c8) by @thegdsks
  • files: apps files ls, set and rm in the CLI (9711b29) by @thegdsks
  • files: app files docs, template file checks and a Gatus template (feae307) by @thegdsks
  • k8simport: map Kubernetes manifests to stack documents with a findings report (ba27ba0) by @thegdsks
  • apps: private app tunnel from the CLI and dashboard (c091157) by @thegdsks
  • store: resource change log with versions, CAS and compaction (b720848) by @thegdsks
  • store: log app changes beside every app write, with backfill (9b37d6c) by @thegdsks
  • cli: yaml, wide, name, custom-columns and jsonpath output formats (8e26907) by @thegdsks
  • import: import k8s command, API route, client and docs (4784a7f) by @thegdsks
  • jobs: run-to-completion one-shot jobs with completions and backoff (3bfb57f) by @thegdsks
  • cli: explain, api-resources, rollout, config contexts and -n/-A scope flags (1068dcd) by @thegdsks
  • api: v2 list, get and watch for apps, nodes and databases (cff5d7f) by @thegdsks
  • files: Files section on the app Configuration tab (863de93) by @thegdsks
  • web: CI gate card on the Source tab and docs (a1ea0af) by @thegdsks
  • templates: plan guarded template upgrades with risk and blockers (c386d3c) by @thegdsks
  • heartbeat: off-host dead-man heartbeat with settings card and docs (01facab) by @thegdsks
  • backup: copy backups to a second destination with lag alert (3f4f3bf) by @thegdsks
  • cli: restart --wait exits on the real outcome, add env unset (ae4336b) by @thegdsks
  • web: second destination copy status on backup settings (94eef35) by @thegdsks

Bug fixes

  • agent: keep container image identity from remote nodes (9201f82) by @thegdsks
  • build failures no longer log a doubled build prefix (a848b33) by @thegdsks
  • installer token gate no longer relies on a guessed cloud-init variable (c038d39) by @thegdsks
  • import: import config emits a file apps create accepts (b6bb144) by @thegdsks
  • auth: concurrent first sign-ins now trust exactly one device (cbd5788) by @thegdsks
  • cli: deploy says when the new URL's certificate is still being issued (f18d730) by @thegdsks
  • compose: reject NaN, overflowing and zero-rounding resource limits (9955eb5) by @thegdsks
  • web: sign-in keeps deploy links and the first-run setup token (6b672cf) by @thegdsks
  • compose: enforce project and team quotas on compose deploys (59e2ea5) by @thegdsks
  • cli: import config refuses and quotes unsafe names in printed commands (757f7fe) by @thegdsks
  • mcp: deploy_app wait follows the deploy it started (ca040c9) by @thegdsks
  • cli: deploy cert wait ends at its window and applies to static deploys (22acd88) by @thegdsks
  • api: block self-approval through the requester's own token (f728b14) by @thegdsks
  • web: keep a link's hash across the sign-in redirect (4fe904f) by @thegdsks
  • api: cap pull request comment refusal audit rows (880e61f) by @thegdsks
  • api: deny self-approval when a requester token is gone (dfb6ee4) by @thegdsks
  • api: keep PR comment refusal reasons and counts in the audit log (278e62c) by @thegdsks
  • ci: docs-only changes no longer trigger Go tests by name suffix (d712dee) by @thegdsks
  • catalog: mosquitto and registry auth use the generated credentials (eb4145d) by @thegdsks
  • catalog: Open Notebook API_URL from domain, licence notes, Authelia fallback (e9914b7) by @thegdsks
  • web: show one open action for a live first app (f96bbc5) by @thegdsks
  • web: one compact HTTPS prompt in the first-app flow (4be8a97) by @thegdsks
  • web: compact first-run path cards on narrow screens (d05350c) by @thegdsks
  • web: live title and real scheme on the first-app screen (2fbb728) by @thegdsks
  • catalog: drop ignored compose keys from three templates (68b3dc1) by @thegdsks
  • apps: keep and admit published ports on app create and update (1339423) by @thegdsks
  • web: first app live state states its status once (acf2f0c) by @thegdsks
  • deploy-urls: retained deploy clones no longer bind published ports (9bb8dd9) by @thegdsks
  • web: one compact HTTPS prompt on first run (ee87213) by @thegdsks
  • compose: cap shm_size by default and count it against memory quota (40468c4) by @thegdsks
  • catalog: keep the Authelia admin password off the command line (efeb9a2) by @thegdsks
  • apps: refuse published ports the control plane or a host port holds (794b28a) by @thegdsks
  • web: 44px tap targets for first-run secondary links on phones (3f0451a) by @thegdsks
  • apps: accept a UDP-only app with no HTTP port on create and edit (0dd838c) by @thegdsks
  • web: only link https release notes from the update strip (1bd0acd) by @thegdsks
  • web: firewall rows keep bind and state together, loopback reads Local only (fcd570e) by @thegdsks
  • web: published port chips carry the container mapping inside (7b62acd) by @thegdsks
  • web: hide the published ports hint while its error shows (f4184fb) by @thegdsks
  • apps: let a portless app edit or clear its published ports (cb08820) by @thegdsks
  • quota: count /dev/shm of apps without a memory limit in usage (e04797a) by @thegdsks
  • api: reject negative resources and oversize shm on app writes (bafdb50) by @thegdsks
  • cli: harden up push check git calls and allowlist it (3e5b804) by @thegdsks
  • web: map authelia and rsshub marks, list five known-missing logos (0c4be3f) by @thegdsks
  • deploy: keep canaries, previews and revives off published host ports (b88325a) by @thegdsks
  • catalog: RustDesk template refuses to start without a relay host (9d2145b) by @thegdsks
  • ports: close published port holes and dial the tcp binding (22226c1) by @thegdsks
  • compose: keep the 2 GiB shm cap when its env value is invalid (88caa56) by @thegdsks
  • domains: refuse a domain on an app with no HTTP port (8e72c92) by @thegdsks
  • catalog: Authelia start fails closed without a valid admin hash (487e8db) by @thegdsks
  • deploy: app.yaml deploys refuse host ports the API would refuse (9914522) by @thegdsks
  • ports: proxy and probes dial the service port, not the first binding (8cad70d) by @thegdsks
  • deploy: app.yaml host_port pins get the API's holder checks (4870709) by @thegdsks
  • publish-lock: publishing a held build rechecks its host ports (5406ac6) by @thegdsks
  • ports: reserve the mesh's configured WireGuard port (ca37316) by @thegdsks
  • cli: up's push check ignores repo git proxy and credential hooks (9224628) by @thegdsks
  • catalog: Authelia keeps users.yml with argon2id or added users (3560d4c) by @thegdsks
  • web: map RustDesk mark and list Radicale as known-missing (c4954e5) by @thegdsks
  • reconcile: exited port-less service no longer reports Ready (4644fe1) by @thegdsks
  • api: claim a deploy approval before applying it (b454a54) by @thegdsks
  • api: stop a stack reject from failing an apply in flight (0a6495e) by @thegdsks
  • reconcile: stop rerunning a one-shot service that exited 0 (b1a9356) by @thegdsks
  • reconcile: honor depends_on service_completed_successfully (b853c41) by @thegdsks
  • deploywatch: ignore a one-shot service that exited 0 (e38401a) by @thegdsks
  • deploy: report a completed one-shot service as rolled out (6d22f18) by @thegdsks
  • apps: keep a one-shot restart policy across health edits (0fef1b9) by @thegdsks
  • reconcile: let a long one-shot finish instead of killing it (47ae3c7) by @thegdsks
  • reconcile: stop counting a never-started one-shot as completed (1ea59f5) by @thegdsks
  • reconcile: judge a completed dependency by its current release only (ed55ad6) by @thegdsks
  • reconcile: keep a worker crash restart from failing its deploy (f32f6ae) by @thegdsks
  • api: return a same-tag approval to pending when its apply never ran (6d303ed) by @thegdsks
  • compose: warn on and ignore a malformed on-failure:N restart value (556e436) by @thegdsks
  • spec: keep run-to-completion on app.yaml and compose build deploys (cc46fbd) by @thegdsks
  • agent: stop counting a never-started remote one-shot as completed (031746c) by @thegdsks
  • deploy: report a one-shot past its completion budget as failed (2abdcab) by @thegdsks
  • stacks: accept a UDP-only app with no HTTP port (7eb7531) by @thegdsks
  • console: run only allowlisted API-only CLI commands (eddeee2) by @thegdsks
  • console: mask secrets and strip escapes in console output (2478ce0) by @thegdsks
  • console: start the CLI in its own session with no extra fds (6619607) by @thegdsks
  • ci: GitLab trusts require protected refs and environments (0ae4d3c) by @thegdsks
  • ci: adding a CI trust needs deploy, custom issuers need root (e3ee537) by @thegdsks
  • ui: restart no longer reports a false failure while recovering (7877ba7) by @thegdsks
  • ci: trusts on the same path no longer collide across providers (b6b0148) by @thegdsks
  • ci: CI token exchanges are audited and old tokens refused (1de7eeb) by @thegdsks
  • web: wrap long notes and tokens in the template result dialog (387c9f9) by @thegdsks
  • web: keep the assistant button clear of page actions on phones (4d41269) by @thegdsks
  • web: 44px tap targets on phones for first-app and confirm buttons (8fefeeb) by @thegdsks
  • web: focus Cancel first and make Stop confirm solid destructive (ea78aba) by @thegdsks
  • web: one HTTPS prompt on the first-app card and no no-op shortcut (d1557e6) by @thegdsks
  • catalog: Authelia says why it stopped when hashing fails (57164b5) by @thegdsks
  • deploy: report a deploy stuck in a crash loop as failed (173683f) by @thegdsks
  • web: show a crash-looping first deploy as failed (9903725) by @thegdsks
  • api: keep omitted fields on PUT /apps instead of clearing them (b121ecb) by @thegdsks
  • web: trust the server deploy outcome for crash-looping apps (e7a27a1) by @thegdsks
  • mcp: app tool output no longer fails on a null env (715ed1a) by @thegdsks
  • PUT app counts Unicode-folded keys as sent (0a24bb0) by @thegdsks
  • CLI console frees the run slot before its exit frame (acc3a5e) by @thegdsks
  • cli: green the CLI tests after the kubectl verbs and new commands (f73d42a) by @thegdsks
  • cli: list heartbeat and upgrade-plan in shell completion (ce412ae) by @thegdsks

Performance

  • api: take the host port lock only for deploys that claim one (716a251) by @thegdsks
  • mcp: slim compact tool schemas, free about 1.5k tokens (1855bea) by @thegdsks

Documentation

Maintenance, CI, and dependency updates (33)

Install

Fresh install on a Linux host, pinned to this release:

curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh | sudo env LEVELRAIL_VERSION=v0.8.7 sh

Upgrade an existing install in place (keeps the unit file and data):

curl -fsSL https://raw.githubusercontent.com/glincker/levelrail/main/install.sh | sudo env LEVELRAIL_VERSION=v0.8.7 sh -s upgrade

Docker Compose: pin the image tag in docker-compose.yml:

services:
  levelrail:
    image: ghcr.io/glincker/levelrail:v0.8.7

Downloads

File What it is
checksums.txt.sigstore.json Control plane
levelrail-agent-linux-amd64 Node agent
levelrail-agent-linux-amd64.deb Node agent
levelrail-agent-linux-amd64.rpm Node agent
levelrail-agent-linux-arm64 Node agent
levelrail-agent-linux-arm64.deb Node agent
levelrail-agent-linux-arm64.rpm Node agent
levelrail-cli-darwin-amd64 Command line tool
levelrail-cli-darwin-arm64 Command line tool
levelrail-cli-linux-amd64 Command line tool
levelrail-cli-linux-arm64 Command line tool
levelrail-cli-windows-amd64.exe Command line tool
levelrail-cli-windows-arm64.exe Command line tool
levelrail-linux-amd64 Control plane
levelrail-linux-arm64 Control plane
release-manifest.json Control plane
checksums.txt SHA-256 of every file

Container images

Multi-arch (linux/amd64, linux/arm64), signed with cosign, SBOM and provenance attached. Also tagged v0.8, latest at release time (moving tags).

Image Tag Digest
ghcr.io/glincker/levelrail v0.8.7 sha256:005ed6ae7acd76b2367015237f850b37554b11b811213bbd1d88901b8597cd21
ghcr.io/glincker/levelrail-agent v0.8.7 sha256:a1180752f65e99e2debd016d5df464c2955023ee010330aeafdb04cb855ae7f8

Verify

Binaries: check downloads against checksums.txt:

gh release download v0.8.7 --repo glincker/levelrail --pattern 'levelrail-linux-amd64' --pattern checksums.txt
sha256sum --ignore-missing -c checksums.txt

Images: verify the keyless signature was made by this repository's release workflow:

cosign verify ghcr.io/glincker/levelrail@sha256:005ed6ae7acd76b2367015237f850b37554b11b811213bbd1d88901b8597cd21 \
  --certificate-identity-regexp '^https://github\.com/glincker/levelrail/\.github/workflows/release\.yml@refs/(heads/main|tags/v.+)$' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Contributors

@thegdsks

Thanks to @thegdsks.

Full changelog: v0.8.6...v0.8.7 | Release page | Installing | Upgrading | Verifying signatures