github psviderski/uncloud v0.18.0

15 hours ago

The main highlights of this release are pre-deploy hooks for running database migrations and a redesigned deployment plan output that makes uc deploy much nicer to read and understand.

On top of that, 0.18.0 also:

  • makes the system ssh CLI the default connection method (with fallback to the Go implementation)
  • adds Compose support for pid, shm_size, and the new x-context extension to pin a Compose file to a cluster
  • brings new docs, a bunch of quality-of-life improvements and bug fixes, read on for the full details!

Pre-deploy hooks

⚠️ This requires both uc and the daemon to be upgraded to v0.18.0

Changes: f4581ea, 1c8b770, 772b31b, 0e820f9

You can now run a one-off command before deploying a service using the new x-pre_deploy Compose extension. This is ideal for database schema migrations, uploading static assets to a CDN, cache invalidation, and any other setup task that needs to run once before new code goes live.

services:
  web:
    build: ..
    environment:
      DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/postgres
    x-pre_deploy:
      # Apply Django migrations from the built image before deploying new app containers.
      command: python manage.py migrate
    depends_on:
      - db

Here is how it's displayed in the deploy plan when you run uc deploy:

The hook command runs in a new container that inherits the service's image, environment variables, volumes, placement, and compute resources.

If the command exits successfully, the deployment continues with a normal rolling update. If it fails or times out, the deployment stops immediately and uc deploy displays the latest hook logs to help you diagnose the issue.

pre-deploy-hook

Container tables in uc ps and uc inspect now also list pre-deploy hook containers.

See the docs:

Restyled deployment plans

Changes: 0f4c211, f5a77b8, b4b1232

The deployment plan output that you see when running uc deploy, uc scale, and uc caddy deploy has been redesigned with consistent styling, clearer operation verbs, and a header and the prompt showing the target context.

We hope this makes it easier for you to understand what changes will be made and to which cluster before you confirm the deployment.

System ssh is now the default connection method

Change: 06c2bc5

The ssh+cli:// connection method that uses your system's ssh CLI is now the default for new connections, so the prefix can be omitted:

# Old
uc machine init ssh+cli://user@host
# New
uc machine init user@host

ssh_cli: can also be replaced with just ssh: in the config file (~/.config/uncloud/config.yaml):

contexts:
  prod:
    connections:
      - ssh: user@host

This will by default use your existing SSH config, agent, keys, ProxyJump, and ProxyCommand setup automatically. You can fall back to the Go native SSH implementation using ssh+go:// prefix.

Combined with the SSH control socket reuse introduced in v0.17.0, this makes most uc commands noticeably faster and removes a whole class of authentication friction.

The new Connecting to a cluster doc walks through all the supported connection schemes (ssh://, ssh+go://, tcp://, unix://), how uc picks a machine to talk to from your config, and how to connect without a config file for CI pipelines and scripts.

Cluster context selection in Compose

Change: 1525d18

You can now pin a Compose file to a specific context using the new x-context extension. This prevents accidentally deploying to the wrong cluster when you switch contexts.

x-context: prod

services:
  web:
    image: myapp

When x-context is set, uc deploy will use that context regardless of your currently selected one in the Uncloud config. The deployment plan output also displays the target context so you always know where your changes are going.

See x-context reference for more details.

Compose pid namespace support

PR: #276. Thanks to @miekg for the contribution ❤️

You can now configure the PID namespace mode for service containers. The most common use case is pid: host, which lets a container see and interact with processes on the host. This is useful for monitoring agents, debuggers, and similar tooling.

services:
  monitoring:
    image: agent
    pid: host

Compose shm_size support

Change: 8ae38cf

You can now set shm_size, the size of the /dev/shm shared memory tmpfs. This is useful for databases like Postgres, headless Chromium, and other workloads that need a larger shared memory segment.

services:
  postgres:
    image: postgres:18
    shm_size: 256mb

Documentation

  • Connecting to a cluster: a complete guide to cluster contexts, connection resolution and all supported types, and how to connect without a config file
  • CLI configuration file: a full reference for the ~/.config/uncloud/config.yaml file, covering contexts, connections, and all supported fields
  • Pre-deploy hooks: a guide for the new feature, with examples for database migrations and other one-off setup tasks
  • Compose extensions: a dedicated reference page for all Uncloud-specific Compose extensions

Improvements

  • The uc CLI and the daemon now exchange versions on every gRPC call and error if they are incompatible. This is a groundwork to make better user experience when releasing breaking changes in the future (#260). Thanks to @jabr for the contribution ❤️
  • New uc exec accepts an optional -- separator before the command, matching Docker and other CLIs (#301). Thanks to @nick-potts for the contribution ❤️
  • New uc docs --manual flag generates manual pages for uc, making it easier for distribution maintainers to package manpages alongside the binary (#302). Thanks to @miekg for the contribution ❤️
  • The daemon now exposes a gRPC method to fetch journald logs from a machine, laying the groundwork for an upcoming uc machine logs command (#282). Thanks to @miekg for the contribution ❤️
  • Warnings are now printed for detected unsupported Compose features (#288). Thanks to @miekg for the contribution ❤️
  • New --auto-confirm flag for uc scale which now always asks for confirmation before changing replica counts
  • New --ulimit flag for uc run to set resource limits
  • bumped Go to 1.26.1 and modernized the codebase using Go 1.26 (#278)
  • Migrated TUI components to lipgloss/v2, bubbletea/v2, and huh/v2

Bug fixes

  • Fixed uc deploy crash in an initialised but empty git repository (#275). Thanks to @tonyo for the contribution ❤️
  • Fixed ucind downloading the wrong Corrosion architecture on arm64 (#285). Thanks to @miekg for the contribution ❤️
  • Fixed output contamination in the SSH CLI executor by separating stdout and stderr (#270)
  • Fixed trying other machine connections when the first one fails for the new default ssh type. Fixed the TUI progress spinner.

Upgrade to 0.18.0

Uncloud CLI locally

To upgrade the Uncloud CLI (uc) locally:

# 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:

# AMD64
curl -fsSL -o uncloudd.tar.gz https://github.com/psviderski/uncloud/releases/download/v0.18.0/uncloudd_linux_amd64.tar.gz
# ARM64
# curl -fsSL -o uncloudd.tar.gz https://github.com/psviderski/uncloud/releases/download/v0.18.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

  • cb77d42 Merge branch 'docs/uncloud-config'
  • b3b33a8 chore(e2e): increase ucind cluster init timeouts, decrease max backoff delay for TCP connection to retry faster
  • 07e380b chore(pre-deploy): warn about depends_on: service_completed_successfully to use pre-deploy hook instead
  • be0f833 chore: add dev:install and dev:reset mise commands to manually test daemon changes on dev machines
  • 2992bad chore: bump Go to 1.26.1 and golangci-lint to 2.11.2 on github actions
  • cf3234a chore: bump Go version to 1.26.1
  • 6cc3a05 chore: bump mise to 2026.3.7 on github actions
  • 9fb20c3 chore: extend Uncloud-in-Docker section in HACKING.md
  • 29a682f chore: generate mise.lock for all platforms
  • 9e39f03 chore: lint
  • 255448a chore: migrate to hub/v2 and bubbletea/v2
  • 33fcb2f chore: migrate to lipgloss/v2
  • a0dbe4a chore: mise ucind:cleanup task to remove ucind managed containers and networks
  • 2ab58d2 chore: modernize the codebase using go 1.26 (#278)
  • 76880d9 chore: move proto generation to mise tasks
  • 18ea1bc chore: remove obsolete Makefile targets
  • 7eaf424 ci: update mise action to v4, ignore changes to mise.lock
  • 12c82bd ci: update the lint workflow to run linter instead of formatter
  • 117c2ab ci: use latest version of mise action for go-tests
  • cef0472 feat(machine-logs): add server side of journal logs (#282)
  • f4581ea feat(pre-deploy): add pre-deploy hook to service spec
  • 1c8b770 feat(pre-deploy): add support for pre-deploy hook containers in service management, sync all containers to store
  • 0e820f9 feat(pre-deploy): add support for x-pre_deploy extension in Compose + e2e test
  • 0da9df1 feat(pre-deploy): correct progress events for pre-deploy hooks, make other container events more aligned with plan
  • 772b31b feat(pre-deploy): implement pre-deploy hook operations for deployment
  • 043b85a feat(pre-deploy): include timeout information in pre-deploy hook formatting in plan
  • 1930bb5 feat(pre-deploy): list hook containers in 'uc ps' and 'uc inspect'
  • 7ec8879 feat: accept optional -- in uc exec (#301)
  • 7f92a5d feat: add --ulimit flag for 'uc run' command
  • f5a77b8 feat: add auto-confirm option for 'uc scale' command, always require confirmation, format scaling plan
  • 897f30f feat: add client/server version check mechanism to gRPC calls (#260)
  • 1525d18 feat: add cluster context support in Compose with x-context extension
  • 8ae38cf feat: add shm_size support in Compose and --shm-size flag for 'uc run' (closes #267)
  • 06c2bc5 feat: make connection method using system 'ssh' the default (add ssh+go:// fallback)
  • d38312f feat: print warning on some unsupported compose features (#288)
  • 98439b7 feat: support PID namespace mode in Compose (#276)
  • eff1bc8 feat: uc docs --manual flag to generate manual pages (#302)
  • e96cce8 fix(pre-deploy): exclude hook containers from caddy and dns controllers
  • a844cc6 fix(pre-deploy): include hook containers in logs, ls, stop commands
  • 3e30a59 fix(pre-deploy): progress event for stopping running hooks
  • 442f1d9 fix: uc deploy should not crash in empty git repository (#275)
  • a1bde30 fix: disable interactive prompts for ssh connections to not interfere with TUI
  • ba73259 fix: get the correct corrosion version in ucind image (#285)
  • 3f95583 fix: plan formatting for service scaling (update verb), fix image and replicas diff
  • ab644f6 fix: race on warned flag in versioncheck pkg, make consistent use of client/server terms
  • d2703cb fix: remove extra line between services in deploy plan
  • 9e4c759 fix: separate stdout and stderr in SSH CLI executor to prevent output contamination (closes #270)
  • cd149e4 fix: spec validation when name is empty, race in e2e tests
  • 940732e fix: sshcli unit test and lint
  • 9aee75b fix: tests
  • 0a9a1db fix: try other connections when ssh+cli connection fails, enable spinner for ssh+cli
  • 37c937a lint
  • 86251a9 lint
  • 883f184 lint
  • 1735ef9 refactor: GetContextOverrideOrCurrent to check if config used
  • e22cdf0 refactor: NewTable for consistent CLI table rendering, style images for ls,ps
  • fe81330 refactor: event ID generation for images, machines, and volumes to align with plan formatting
  • 0f4c211 refactor: format compose deployment plan with style, display target context
  • b4b1232 refactor: format deployment plan for caddy (uc caddy deploy)
  • 4b34c42 refactor: modernize, remove AsPtr (#300)
  • 15037f3 refactor: more descriptive error for using --connect with 'uc machine init'
  • 30bcb02 refactor: move StopGracePeriod from ServiceSpec to ContainerSpec
  • 62976f3 refactor: print warnings for all detected unsupported Compose features, not only first one
  • ada9bec refactor: remove docker dependency for Pid container property
  • 21c65b9 refactor: remove irrelevant property from pid unit test
  • 636307d refactor: replace tabwriter with a Table for consistent table rendering across commands
  • e4cb71b refactor: simplify and speed up plan output formatting by removing name resolver dependency
  • 943fea0 refactor: simplify journal logs following, fix corrosion unit name
  • 68661e5 refactor: tui package for CLI styles and prompts, restyle confirmation
  • 838839a refactor: update deployment plan structure to use typed volume and service operations

Don't miss a new uncloud release

NewReleases is sending notifications on new releases.