v0.17.0

gristlabs/grist-corev0.17.0Mar 1, 2026by psviderski

AI Summary

Major release introducing container health monitoring with automatic rollback, enhanced Compose spec support for health checks and device mapping, and improved deployment reliability.

Key Highlights

  • Automatic rollback during rolling deployments if containers crash or become unhealthy
  • Compose `healthcheck`, `devices`, and `ulimits` support
  • Control over container replacement order (start-first vs stop-first)

New Features

  • Health monitoring and auto-rollback
  • Device mapping for host GPU access
  • SSH connection reuse via control socket
  • Auto-provisioning of volumes for global services

Full Release Notes

This release brings container health monitoring with automatic rollback during rolling deployments, Compose spec support for `healthcheck`, `devices`, and `ulimits`, and various reliability improvements.

## ✨ Highlights

### Container health monitoring and rollback

Changes: [7a9eac5](https://github.com/psviderski/uncloud/commit/7a9eac593f9be0f02b42b1bef5b82f311e6af243), [7b88040](https://github.com/psviderski/uncloud/commit/7b88040c73a43e1dea8db79513fec1c3cd5eac79), [ce3cb8a](https://github.com/psviderski/uncloud/commit/ce3cb8a34f3ae027a4c17b3425eb58c466ce3dbc)

Rolling deployments now monitor crashes and health checks after starting new containers. If a container keeps restarting or becomes unhealthy, the deployment automatically rolls it back and fails to prevent downtime.

https://github.com/user-attachments/assets/4ee73048-9ca2-4c8a-b075-f8c6a0840ee7

#### Compose `healthcheck` support

Compose files now support the [`healthcheck`](https://github.com/compose-spec/compose-spec/blob/main/spec.md#healthcheck) attribute, allowing you to define health checks for your services:

```yaml
services:
  app:
    image: myapp
    healthcheck:
      test: curl -f http://localhost:8000/health
      interval: 5s
      retries: 3
      start_period: 10s
      start_interval: 1s
```

Use `uc deploy --skip-health` flag to bypass health monitoring for faster emergency deployments.

See [Rolling deployments](https://uncloud.run/docs/guides/deployments/rolling-deployments) for more details on how rolling deployments work and how to configure health checks for your services.

### Control container replacement order during rolling deployments

PR: [#248](https://github.com/psviderski/uncloud/pull/248). Thanks to @nick-potts for the contribution ❤️

You can now control the order of container replacement during rolling deployments with `deploy.update_config.order` in your Compose file:
- `start-first` (default): starts a new container before stopping the old one
- `stop-first`: stops the old container before starting a new one (brief downtime)

```yaml
services:
  app:
    image: myapp
    deploy:
      update_config:
        order: stop-first
```

The default order automatically switches to `stop-first` if a service mounts a volume to prevent data corruption.

See [Rolling deployments](https://uncloud.run/docs/guides/deployments/rolling-deployments) for more details.

### Compose `devices` support

PR: [#250](https://github.com/psviderski/uncloud/pull/250). Thanks to @jabr for the contribution ❤️

You can now map host devices into containers, for example, Intel integrated GPU for video transcoding using the [`devices`](https://github.com/compose-spec/compose-spec/blob/main/spec.md#devices) attribute in your Compose file:

```yaml
services:
  app:
    image: myapp
    devices:
      - /dev/dri:/dev/dri
      - /dev/ttyUSB0:/dev/ttyUSB0:rw
```

### Compose `ulimits` support

PR: [#244](https://github.com/psviderski/uncloud/pull/244). Thanks to @ipaddicting for the contribution ❤️

You can now set [`ulimits`](https://github.com/compose-spec/compose-spec/blob/main/spec.md#ulimits) for service containers in your Compose file. For example, to increase the maximum number of open files:

```yaml
services:
  app:
    image: myapp
    ulimits:
      nofile:
        soft: 65536
        hard: 65536
```

### Auto-provision volumes for global services

PR: [#243](https://github.com/psviderski/uncloud/pull/243). Thanks to @zasdaym for the contribution ❤️

When deploying a [global service](https://uncloud.run/docs/guides/deployments/deploy-global-services) with a volume, the volume is now automatically created on all machines in the cluster.

## Improvements

- SSH connections with `ssh+cli://` prefix (use `ssh` CLI instead of Go native SSH implementation) reuse a single SSH connection via control socket - significantly speeds up `uc` commands
- Improved `uc image push` support on macOS by always running proxy to virtualised Docker (except OrbStack that doesn't require it)
- Global service deployment stops all running conflicting containers, e.g. left from interrupted deploys, not just the first one
- Temporary socat proxy containers created by `uc image push` are labeled with `uncloud.managed`

## Bug fixes

- Fixed IPv6 address formatting for HTTP URLs ([#254](https://github.com/psviderski/uncloud/pull/254))
- Fixed `uc image push` when using Rancher Desktop locally ([#251](https://github.com/psviderski/uncloud/pull/251))
- Fixed `uc machine init` to reset an already initialised machine when using `ssh+cli://` connection

## Upgrade to 0.17.0

### Uncloud CLI locally

To upgrade the Uncloud CLI (`uc`) locally:

```bash
# Homebrew (macOS, Linux)
brew upgrade uncloud

# Install script (macOS, Linux)
curl -fsS https://get.uncloud.run/install.sh | sh
```

### Machine daemon

To upgrade the Uncloud daemon on your machines, run the following commands on each machine:

```bash
# AMD64
curl -fsSL -o uncloudd.tar.gz https://github.com/psviderski/uncloud/releases/download/v0.17.0/uncloudd_linux_amd64.tar.gz
# ARM64
# curl -fsSL -o uncloudd.tar.gz https://github.com/psviderski/uncloud/releases/download/v0.17.0/uncloudd_linux_arm64.tar.gz
tar -xf uncloudd.tar.gz
sudo install uncloudd /usr/local/bin/uncloudd
rm uncloudd uncloudd.tar.gz
sudo systemctl restart uncloud
```

## Changelog
* b48ebe2acc6035f403623e0d52cef7fb21259129 chore: UNCLOUD_HEALTH_MONITOR_PERIOD accepts duration (10s, 500ms, 0)
* f8d1945544400e8488c721eaf593a352ce3c4400 chore: add TODO for ReplaceContainerOperation
* fe56d6d7083abd00c9e3f132acea03300f68abbd chore: always run proxy to virtualised Docker on macOS for 'image push' except OrbStack
* f48dc250a910f7a11cfeee45cd89fb274e779661 chore: fix landing navbar github/discord buttons wrap on mobile
* 44013da33284511d4712c5eaa670110774ea6785 chore: format AGENTS, instruct to not use em dashes
* 6e59657fe2fb1d00a3b218689e47e0772e193b73 chore: global reconciliation: stop all running conflicting containers, not only replace the first one
* a5a9ef5444c36a32f1828d17be6e432206e375b2 chore: init container healthcheck const
* 87e49dfb62dcf318f39f0cd9a9b12f41ea1cf10b chore: label temporary socat proxy containers created by 'uc image push' with uncloud.managed
* 215f21439d49ea598a66b2f8873dd7fd5c1a2021 chore: lint and fix e2e deploy tests with ReplaceContainerOperation
* c91a9645137cf616acbfdb1f4bfb4d91880be89f chore: make ssh+cli connections reuse one SSH connection via control socket. Fix image push
* 185cf19a0c25ce029da0870265d58e62ab37a4bd chore: minor full-spec test change
* 1d4dbd96ce9113e7e357a07473c6544e79ff6db6 chore: minor sshcli refactgor
* 5c54e9d0595f51574cdf3888734d2213f008079e chore: refactor device mapping to be compliant with Compose (CDI requests)
* 93d7f29d316c48d9844b99f7651db2759dd6390c chore: remove TODO about encapsulating Client in deploy operations
* 808bda67d4fbbe4f3671f37396c404b84286866b chore: remove unused constants
* 2588279e52e8c7b4a9f9440d867f8a63d1371b36 chore: rename AI.md to AGENTS.md
* e6705599b334756a1b81a0109026c1b2216ed75a chore: rename env var UNCLOUD_DEFAULT_HEALTH_MONITOR_PERIOD_MS -> UNCLOUD_HEALTH_MONITOR_PERIOD_MS
* 7c4f739d07f33cd0093890dbad299607bb0e1a98 chore: specify machines to deploy website to
* 18ebd29032fc5b50358643e9595582c927c4424c chore: split deploy operations into separate files in operation package
* e0a63a3f493668bb85c9f8099d6a2ea2d9622e31 chore: typo
* 4443fa9e0e896104391c7b5b99bdf92875f8a694 chore: update full-spec test to include latest implemented Compose attributes
* 0b2e1bb7a222a7873b678c74aed957e4490305b0 chore: update newsletter form to substack
* 53bf446502f1142238a54a6d3c15805042f0e0c3 deploy.update_config.order support to start-first or stop-first when replacing containers (#248)
* ab6f8569878dbadc39bc280f1c9424003e86a9ba feat: Add support for compose `devices` mappings (#250)
* ce3cb8a34f3ae027a4c17b3425eb58c466ce3dbc feat: add --skip-health flag to bypass health monitoring during container deployment
* 17c1bb5c21da254ab4b02061b2162f14adda6b33 feat: add WaitContainerHealthy client method and health check utilities
* 3056e2af114681063a841ae7cdfce526f8bb4f19 feat: add support for healthcheck in Compose
* 3bd940005181c93614c2eae9f9925f78df89eb37 feat: add support for ulimits in compose and container creation (#221) (#244)
* 15d9ceb4d1857846823dbe30b57141a92433287d feat: auto-provision volumes on all machines for global services (#243)
* 7a9eac593f9be0f02b42b1bef5b82f311e6af243 feat: implement container health monitoring and rollback during rolling deployment (closes #24)
* 14056cc58424660b6b9b83ca81756c06bad46b83 fix: format IPv6 addr correclty for HTTP URL (#254)
* 7bfaf311387243adce676ff5caa82107640f7870 fix: image tag template formatting in docs
* 2940965e31fbf62a652da25515e8d862ec079721 fix: recreate container on ulimit changes, add test
* 476a2d57caf7a67b5dc64890365ea10d1632c11e fix: reset already initialised machine on 'uc machine init' when using ssh+cli connection
* 7b88040c73a43e1dea8db79513fec1c3cd5eac79 fix: rolling container replacement: if new container fails, rollback and run old container only if it was running
* ce46a67d6df342f0a03606a0ec2c5e91c6827506 fix: ssh args for machine init/add when using ssh+cli
* a4a8e70f9cff776b7323b368684b69ecfee91677 fix: sshcli tests
* d3ee7399eb06142f86abc34cb91665ee27c56b68 fix: support image push when using Rancher Desktop locally (#251)