--- sidebar_position: -21.0 sidebar_label: v0.21.0 --- # v0.21.0 This page mirrors the [GitHub release](https://github.com/psviderski/uncloud/releases/tag/v0.21.0), which also includes the full list of commits. This release brings **shared TLS certificate storage for Caddy**, **systemd socket activation**, **runtime templates**, and a way to use **your own cluster domain**. It also adds a certificate inventory command, faster service listing, and fixes for proxying, container logs, and terminal output. ## ⚠️ Breaking changes {#breaking-changes} - The API socket moved from `/run/uncloud/uncloud.sock` to `/run/uncloud/api/uncloud.sock` ([f68c985](https://github.com/psviderski/uncloud/commit/f68c985)). Update your custom tools and container mounts if you used the API socket directly. Both old and new `uc` versions handle the socket move automatically. ## Shared certificate storage for Caddy Caddy module: [caddy-uncloud](https://github.com/unlabs-dev/caddy-uncloud), issue: [#31](https://github.com/psviderski/uncloud/issues/31) If you run Caddy on multiple machines behind a load balancer or a DNS record with multiple IPs, certificate issuance may not work correctly. The new Uncloud storage module lets Caddy instances share certificates, private keys, and challenge tokens through the cluster store. Any instance can read the token to answer a challenge, and once one obtains a certificate, the others can use it too. Distributed locks coordinate issuance across machines. Shared storage is **opt-in** for now. See [Cluster storage for Caddy](/docs/concepts/ingress/cluster-storage-for-caddy) for more details. ## Inspect Caddy certificates Changes: [930e7ea](https://github.com/psviderski/uncloud/commit/930e7ea), [9c21ae6](https://github.com/psviderski/uncloud/commit/9c21ae6) The new [`uc caddy cert ls`](/docs/cli-reference/uc_caddy_cert_ls) command lists certificates in Caddy's shared cluster storage. This is handy for checking which certificates have been issued and when they expire. ```shell uc caddy cert ls ID NAME ISSUER EXPIRES c111e23615f7 dns.uncloud.run Let's Encrypt 2026-12-31 (2 months) b5dcd2a03e1b nginx.2t5ex2.uncld.dev Let's Encrypt 2026-12-31 (2 months) 70707fd2fea2 test-staging.2t5ex2.uncld.dev Let's Encrypt (staging) 2026-12-31 (2 months) c5f9301e1c06 uncloud.run Let's Encrypt 2026-12-31 (2 months) ``` ```shell uc caddy cert ls --machine machine-1 uc caddy cert ls -o json ``` This requires Caddy to first be deployed with [cluster storage](/docs/concepts/ingress/cluster-storage-for-caddy). ## Systemd socket activation Change: [f68c985](https://github.com/psviderski/uncloud/commit/f68c985) Systemd now creates the Uncloud API socket and passes it to the daemon when it starts. The socket is available before Docker starts and stays in place across daemon restarts. This gives Caddy's cluster storage module and other extensions a stable API socket, including after a reboot. ## Runtime templates for bind mounts Change: [5c33e4b](https://github.com/psviderski/uncloud/commit/5c33e4b) You can now use per-container metadata in bind mount paths. Uncloud renders these Go templates on the destination machine just before creating each container, so every replica can get its own host directory: ```yaml services: app: image: app:latest scale: 2 volumes: - "/var/lib/app/{{.Container.Name}}:/data" ``` For now, runtime templates expose `.Container.Name` and work only in the host and container paths of bind mounts. They could easily be extended to other metadata fields and Compose attributes. Please share your use case on [#431](https://github.com/psviderski/uncloud/issues/431). See [Runtime templates](/docs/concepts/services/runtime-templates) for more details and examples. ## Use your own cluster domain PR: [#365](https://github.com/psviderski/uncloud/pull/365). Thanks to [@miekg](https://github.com/miekg) for the contribution ❤️ The new [`uc dns set`](/docs/cli-reference/uc_dns_set) command lets you use a domain you manage yourself as the default cluster domain for generated service hostnames: ```shell uc dns set apps.example.com ``` Configure wildcard DNS records for `*.apps.example.com` with your DNS provider, pointing to machines running Caddy. New services published without an explicit hostname can then use addresses like `web.apps.example.com`. Uncloud doesn't create or manage those external records. If your cluster already has a reserved `*.uncld.dev` domain, release that reservation with `uc dns release` first. ## Improvements - `uc ls` now collects services and containers with a single broadcast request instead of inspecting every service separately. This significantly speeds it up, especially when you have many services ([0e53f50](https://github.com/psviderski/uncloud/commit/0e53f50)). - Compose now supports `stdin_open` and `tty` ([#419](https://github.com/psviderski/uncloud/pull/419)). Thanks to [@miekg](https://github.com/miekg) for the contribution ❤️ - Compose warns about more unsupported options, including external configs, `container_name`, and `deploy.placement` ([#429](https://github.com/psviderski/uncloud/pull/429)). Thanks to [@miekg](https://github.com/miekg) for the contribution ❤️ - `uc machine init/add` now accept `UNCLOUD_DAEMON_VERSION` as an alternative to `--version`, useful for scripts and nightly setups ([#409](https://github.com/psviderski/uncloud/pull/409)). Thanks to [@tonyo](https://github.com/tonyo) for the contribution ❤️ - Caddy deployments now have a healthcheck that queries the admin API, so the deployment waits for Caddy to load its config before treating a new container as healthy ([70de7b1](https://github.com/psviderski/uncloud/commit/70de7b1)). - The [installation docs](/docs/getting-started/install-cli) now include mise ([#421](https://github.com/psviderski/uncloud/pull/421)). ## Bug fixes - Preserve custom global Caddy configuration during regeneration on Caddy restart. `uc caddy config` now warns when the last attempt to load the config failed ([ace8cbf](https://github.com/psviderski/uncloud/commit/ace8cbf)). - Keep `uc proxy` running when an individual client disconnects or a forwarded connection fails. Connection errors now include more useful troubleshooting information ([fa77edf](https://github.com/psviderski/uncloud/commit/fa77edf)). - Stream logs correctly from containers with an allocated TTY ([#419](https://github.com/psviderski/uncloud/pull/419)). - Stop terminal capability replies from leaking into the shell after CLI spinners finish ([#435](https://github.com/psviderski/uncloud/pull/435)). Thanks to [@tonyo](https://github.com/tonyo) for the contribution ❤️ - Fix shell completion when using `--connect`, `--context`, or `--uncloud-config` ([351698c](https://github.com/psviderski/uncloud/commit/351698c)). - Return a non-zero exit code consistently when a command is cancelled by declining a confirmation prompt ([#406](https://github.com/psviderski/uncloud/pull/406)). Thanks to [@miekg](https://github.com/miekg) for the contribution ❤️ - Extend the systemd startup timeout while pulling the Corrosion image, allowing up to 5 minutes for a slow pull ([dc721e5](https://github.com/psviderski/uncloud/commit/dc721e5)). - Fix daemon version comparisons when upgrading from a nightly build to the latest stable release ([50f8fbc](https://github.com/psviderski/uncloud/commit/50f8fbc)). - Avoid waiting on replication gaps from unavailable cluster members after the requested store versions have been reached ([e4bd1ad](https://github.com/psviderski/uncloud/commit/e4bd1ad)). ## Upgrade to v0.21.0 Upgrade your local CLI and the daemon on every machine. If you're upgrading from before v0.20.0, follow the [v0.20.0 upgrade instructions](https://github.com/psviderski/uncloud/releases/tag/v0.20.0#upgrade-to-0200) first for the Corrosion migration. ### Uncloud CLI locally ```bash # Homebrew (macOS, Linux) brew upgrade uncloud # Install script (macOS, Linux) curl -fsS https://get.uncloud.run/install.sh | VERSION=0.21.0 sh ``` ### Machine daemon Run the following commands over SSH on each machine to upgrade the daemon binary: ```bash ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') curl -fsSL -o uncloudd.tar.gz https://github.com/psviderski/uncloud/releases/download/v0.21.0/uncloudd_linux_${ARCH}.tar.gz tar -xf uncloudd.tar.gz sudo install uncloudd /usr/local/bin/uncloudd rm uncloudd uncloudd.tar.gz ``` **The following systemd unit updates are only needed on existing machines.** New machines set up with `uc machine init` or `uc machine add` using v0.21.0 or later install these units automatically. Replacing the daemon binary alone on an existing machine doesn't install the new `uncloud.socket` unit or update `uncloud.service`. Create `/etc/systemd/system/uncloud.socket`: ```bash sudo tee /etc/systemd/system/uncloud.socket >/dev/null <<'EOF' [Unit] Description=Uncloud API socket Before=docker.service [Socket] ListenStream=/run/uncloud/api/uncloud.sock SocketUser=root SocketGroup=uncloud SocketMode=0660 DirectoryMode=0750 [Install] WantedBy=sockets.target EOF ``` Run this command to add the socket dependency directly to `/etc/systemd/system/uncloud.service`: ```bash sudo sed -i \ 's/^After=.*$/Requires=uncloud.socket\ After=network-online.target uncloud.socket docker.service/' \ /etc/systemd/system/uncloud.service ``` Stop the daemon before starting the socket unit, then reload systemd, enable the socket, and start the upgraded daemon: ```bash sudo systemctl stop uncloud.service && \ sudo systemctl daemon-reload && \ sudo systemctl enable uncloud.socket && \ sudo systemctl start uncloud.socket && \ sudo systemctl start uncloud.service ``` ### After upgrading Check your CLI and daemon versions: ```shell uc version uc machine ls ```