Repository navigation
v0.8.7
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
- explain previous-release hold and rollback pins (b92be07) by @thegdsks
- explain retained deploy containers and when they stop (5780b0e) by @thegdsks
- add deploy and debug from an AI agent flows to MCP recipes (eed5305) by @thegdsks
- ci: tested pipeline files for GitHub OIDC, GitLab and CircleCI (d625495) by @thegdsks
- adr: propose promote from pull request comments (e17647e) by @thegdsks
- adr: require resolved-human self-approval check for PR promote (40287c0) by @thegdsks
- note that chat approvals trust the channel, not a person (0bde83b) by @thegdsks
- setup: show the setup link with the token in the hash (8c01eeb) by @thegdsks
- adr: plan UDP ports, then gated NET_ADMIN and sysctls (3bc187c) by @thegdsks
- catalog: mark seven new templates verified (db53b46) by @thegdsks
- compose: document UDP published ports and what is not yet supported (e93a5ad) by @thegdsks
- compose: fix UDP ports page link and DNS example (f519c7e) by @thegdsks
- udp: examples verified by running them (54dcf05) by @thegdsks
- compose: document shm_size and platform hardening keys (58e2eca) by @thegdsks
- describe the template description field for authors (6cfeb36) by @thegdsks
- compose: document run-to-completion restart and completed depends_on (e399a51) by @thegdsks
- console: add CLI console page and list both beta features in status (523e8c1) by @thegdsks
- stacks: published ports and restart in app documents (c5acde9) by @thegdsks
- ci: deploy from GitLab CI and CircleCI with OIDC, no stored token (856c015) by @thegdsks
- console: document the allowlist, drift tests and per-mode limits (836d37e) by @thegdsks
- ci: GitLab safe defaults, audit entries and downgrading (57ccb0c) by @thegdsks
- deploy_template tool, PUT keep semantics and template Access details (f2db211) by @thegdsks
- refresh the MCP tool surface numbers (55fb6ad) by @thegdsks
- self-hosted guide no longer says autoscaling is missing (aee69c4) by @thegdsks
- api: regenerate the API reference with v2 and tunnel routes (58e0c6c) by @thegdsks
Maintenance, CI, and dependency updates (33)
- apps create rejects databases and env from sections (b68f635) by @thegdsks
- dedupe check uses a key the local parse really warns on (385190a) by @thegdsks
- compose: compose limit env vars use the APP_ prefix (c61272b) by @thegdsks
- deploy link auth test builds its own route tree (f7e7328) by @thegdsks
- e2e: catalog batch2 boot failures print the container log tail (a3ebbea) by @thegdsks
- catalog: fail on $$ in template compose, fix heyform and paymenter redis auth (a4902db) by @thegdsks
- merge release/v0.8.8 into release/v0.8.9 (f93e672) by @thegdsks
- exposure: pin UDP handling of DOCKER-USER rules apart from TCP (8c9cb4c) by @thegdsks
- web: sidebar logo badge keeps unhealthy states visible (6cc23a6) by @thegdsks
- web: HTTPS card test follows the shorter sign-in note (8a4b5b0) by @thegdsks
- web: link mock keeps its class so the tap target is checked (02c514b) by @thegdsks
- e2e: UDP published ports through the platform (cd7782c) by @thegdsks
- iac: regenerate published resources schema (8abbcc0) by @thegdsks
- api: health discovery fakes report real container ports (bd4f0f0) by @thegdsks
- api: Go batch template descriptions reach the catalog API (7c18492) by @thegdsks
- ci: turn SonarCloud off behind SONAR_ENABLED (f350a65) by @thegdsks
- ci: coverage no longer runs on or blocks pull requests (14a2e22) by @thegdsks
- ci: skip heavy test lanes on draft pull requests (e27df98) by @thegdsks
- ci: move the CI required verdict into a script (4e5c137) by @thegdsks
- ci: table-test the CI required verdict (fafcb9a) by @thegdsks
- ci: run CI when the required-check verdict script changes (395713b) by @thegdsks
- stacks: published ports pass admission, drift and rollback (57a72a9) by @thegdsks
- ui: palette restart and stop reuse the shared confirm (542fe0d) by @thegdsks
- compose: cover restart notices after run-to-completion landed (50e0acd) by @thegdsks
- api: allowlist the CI token exchange in the body-ref guard (3d1ff51) by @thegdsks
- agent: assert the exact capability set including exit_times (dfb8233) by @thegdsks
- e2e: keep exit state visible through the pull retry runtime (a90e267) by @thegdsks
- e2e: run-to-completion services through the platform (83faa25) by @thegdsks
- api: align app update tests with keep-omitted semantics (f263e5d) by @thegdsks
- Merge pull request #1400 from glincker/release/v0.8.8 (f5a826b) by @thegdsks
- merge main into release/v0.8.9 (089822b) by @thegdsks
- Merge pull request #1402 from glincker/release/v0.8.9 (e163305) by @thegdsks
- body ref guard treats pointer-filling decoders as decoders (56eff37) by @thegdsks
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 shUpgrade 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 upgradeDocker Compose: pin the image tag in docker-compose.yml:
services:
levelrail:
image: ghcr.io/glincker/levelrail:v0.8.7Downloads
| 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.txtImages: 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.comContributors
Thanks to @thegdsks.
Full changelog: v0.8.6...v0.8.7 | Release page | Installing | Upgrading | Verifying signatures