All releases

v0.4.13

Signedpublished August 21, 2026

What changed

Added

  • Choose which domain a workspace subdomain is published under. Settings has a Base domains section: add a suffix, mark one as the default, rename one, or remove one you no longer use. A deployment used to have exactly one suffix for app subdomains, fixed at install time in config.yaml, and changing it meant re-running the installer over SSH.

    Renaming a base domain moves every subdomain published under it at once, and no workspace restarts — app subdomains are routed from Traefik's file provider, not baked into the container. Where a deployment has more than one suffix, the create and detail pages let you pick per subdomain, so two workspaces can each publish "api" under different domains. Deployments with a single suffix see no picker and nothing changes for them.

    Your installed domain is kept: it seeds the list on first boot and is then left alone, so re-running the installer cannot revert a list you have edited in Settings. Existing subdomains keep routing exactly as before.

  • Install without the workspace image. The installer takes --workspace-image=no, which brings up the server, dashboard and API without downloading the ~750 MB workspace image — around 45 MB and a couple of minutes instead of the better part of a gigabyte and twenty. Everything except creating a workspace works, and when you want the image, re-running the installer with --workspace-image=yes downloads that image and nothing else.

    Most useful when you are standing a host up to look at it, testing an upgrade, or working on a small disk. The answer is remembered, so an upgrade will not quietly start — or stop — fetching it, and --dry-run tells you which way the next run would go. While there is no image the closing banner says workspace image: NOT INSTALLED, and trying to create a workspace names the command that fixes it rather than failing cryptically.

Fixed

  • Upgrades no longer abort claiming they introduced foreign-key violations. A migration that rebuilds a table to add a foreign key renumbers the ones already on it, and the integrity check read the pre-existing orphans it had merely copied as damage it had just done. It now keys violations on the tables involved, so an upgrade is judged on what it actually changed.

Container images

registry build 21
amd64747 MB
sha256:1e94ab774cd53c2444be1bfc7f623a6d93afc4ba50da0bdbba3e82d4d481fa5b
Download
arm64621 MB
sha256:9e7edd3a2d3383a642e2cbc105f6cb71bdfa1cab5736072f64943709572f150c
Download
registry build 21
amd6445 MB
sha256:b76295e064041b5d1b2c284c13879b53817dcc2cf38bed2c8ad96ee849b040ca
Download
arm6444 MB
sha256:23a1486848d5ed290c5ebe5508d0a3f0be76ba58753d447793a3f3c284d30549
Download

Installer files

docker-compose.yml16 KBsha256:80cdf4da7d1527c13fcbe3a8726b9fe67117b47a9152ed13f269abf3e0391ad3
install.sh130 KBsha256:eeb89c7269ca5a25b54ac0bfe3bb27e1cb4ab711f976ddc6bf6622f98d2756f0
traefik-dynamic-http.yml5 KBsha256:e344c8efd13c7d84996e2ebfbc75dcee2d995d8538c8a245c89c0e44fad0089b
traefik-dynamic.yml6 KBsha256:d18fa561b8eb7d53b015284e0246b2d05953bf281b65269c1fae3d6883530db6
uninstall.sh31 KBsha256:d8dc586f38e0cf33eadc126d75b303c660e970e55028f60ad4e2872c40cbaa71

Signature

ecdsa-p256-sha256key f1f1eaf642454d65

One signature covers every artifact above. It is made off this host, and neither this site nor the registry behind it can check it — that is the point, and it is why verifying it catches things a checksum from the same server cannot. How to verify it.

Verify devgrail-container (amd64)
curl -fsSL https://web-dev.trixibot.com/api/registry/releases/v0.4.13 -o release.json

# -j, not -r: -r appends a newline the signer never saw, and the check fails.
jq -j '.signature.payload'   release.json > payload
jq -r '.signature.signature' release.json | base64 -d > payload.sig

openssl dgst -sha256 -verify devgrail-release.pem -signature payload.sig payload
# -> Verified OK

# The payload must name this release, so an older signed one cannot be replayed.
head -2 payload

# ...and it must name this exact file. -qxF: whole line, literal.
grep -qxF 'image devgrail-container 21 amd64 1e94ab774cd53c2444be1bfc7f623a6d93afc4ba50da0bdbba3e82d4d481fa5b' payload && echo "digest is covered by the signature"
The signed payload — shown for reading, not for verifying

Copy this from the manifest with jq -j, never from this page: the signature covers exact bytes, and rendering here drops the trailing newline the signer included.

devgrail-release-signature-v1
release v0.4.13
asset docker-compose.yml 20 80cdf4da7d1527c13fcbe3a8726b9fe67117b47a9152ed13f269abf3e0391ad3
asset install.sh 20 eeb89c7269ca5a25b54ac0bfe3bb27e1cb4ab711f976ddc6bf6622f98d2756f0
asset traefik-dynamic-http.yml 19 e344c8efd13c7d84996e2ebfbc75dcee2d995d8538c8a245c89c0e44fad0089b
asset traefik-dynamic.yml 20 d18fa561b8eb7d53b015284e0246b2d05953bf281b65269c1fae3d6883530db6
asset uninstall.sh 20 d8dc586f38e0cf33eadc126d75b303c660e970e55028f60ad4e2872c40cbaa71
image devgrail-container 21 amd64 1e94ab774cd53c2444be1bfc7f623a6d93afc4ba50da0bdbba3e82d4d481fa5b
image devgrail-container 21 arm64 9e7edd3a2d3383a642e2cbc105f6cb71bdfa1cab5736072f64943709572f150c
image devgrail-server 21 amd64 b76295e064041b5d1b2c284c13879b53817dcc2cf38bed2c8ad96ee849b040ca
image devgrail-server 21 arm64 23a1486848d5ed290c5ebe5508d0a3f0be76ba58753d447793a3f3c284d30549