v0.13.0
psviderski/uncloudv0.13.0Oct 10, 2025by psviderski
AI Summary
Focused on unregistry integration to push images directly to cluster machines, image inspection capabilities, and expanded Compose support with configs and internal DNS improvements.
Key Highlights
- Unregistry integration for direct image push
- Inspect images on machines (uc images)
- Compose configs support
- Internal DNS improvements with machine-scoped entries
- Containerd image store integration
New Features
- unregistry integration for image push
- uc images command to list images
- Compose configs support
- Machine-scoped DNS entries (machine-id.m.service.internal)
- containerd image store by default
- UNCLOUD_MACHINE_ID environment variable
Full Release Notes
This release features **3 weeks of work** from **3 contributors**. It's focused on [unregistry](https://github.com/psviderski/unregistry) integration and expanding Compose support.
## Highlights
### Unregistry integration (push images to cluster)
We've integrated [unregistry](https://github.com/psviderski/unregistry) to make image distribution way easier. You can build your Docker images locally or on CI and push them directly to your Uncloud cluster without needing an external registry. Only the missing layers are transferred, making it efficient and fast.
```shell
# Push local Docker image to a specific or multiple machines.
uc image push IMAGE [-m/--machine NAME[,NAME]]
# Push local Docker image to all machines.
uc image push IMAGE -m all
```
See [`uc image push` documentation](http://uncloud.run/docs/cli-reference/uc_image_push) for more details and examples.
[<DEMO video>](https://github.com/user-attachments/assets/ab356c6a-5286-4a37-84fe-4e4f0bcc7ad8)
Under the hood, `uncloudd` daemon on each machine runs an embedded unregistry server that handles the image receiving and storage in `containerd`. `uc image push` requires [`containerd image store`](https://docs.docker.com/engine/storage/containerd/) to be enabled for Docker on the target machines.
This brings us one step closer to an end-to-end `uc deploy` experience which will handle building, pushing, and deploying images in one go.
### Inspect images
You can now inspect what images you have on your machines in the cluster.
```shell
# List all images on all machines.
uc images
# List images on specific machines.
uc images -m machine1,machine2
# List images filtered by name pattern.
uc images "myapp:1.*"
```
See [`uc images` documentation](http://uncloud.run/docs/cli-reference/uc_images) for more details and examples.
<img width="1109" height="221" alt="Screenshot 2025-10-10 at 6 53 47 pm" src="https://github.com/user-attachments/assets/0561babc-802f-4397-9a92-356d6baa0087" />
[<SCREENSHOT with IN USE column>](https://github.com/user-attachments/assets/d602dd66-c514-4c70-9f28-b91034c79f3d)
### Compose configs
PR: [#116](https://github.com/psviderski/uncloud/pull/116) Thank you @tonyo for the contribution! ❤️
Uncloud now supports [Compose configs](https://github.com/compose-spec/compose-spec/blob/main/08-configs.md) for managing configuration files in your services. Configs allow you to store non-sensitive configuration data separately from your container images and mount them into containers at runtime.
Example `compose.yaml` using configs:
```yaml
services:
app:
image: myapp:latest
configs:
- source: app_config
target: /app/config.yaml
configs:
app_config:
# Local path is relative to compose.yaml location
file: ./config.yaml
```
See [Configs documentation](http://uncloud.run/docs/concepts/compose/configs) for more details.
### Internal DNS improvements
PR: [#123](https://github.com/psviderski/uncloud/pull/123) Thank you @jabr for the contribution! ❤️
New machine-scoped DNS entries `<machine-id>.m.<service-name>.internal` allow targeting services on specific machines.
This is useful for debugging, health checks, or machine-specific routing needs.
See [Internal DNS documentation](http://uncloud.run/docs/concepts/services/internal-dns) for more details.
### Containerd image store integration
Uncloud now automatically configures Docker to use the [containerd image store](https://docs.docker.com/engine/storage/containerd/) by default on new machines, enabling:
- `uc image push` feature to push images directly to the cluster machines via [unregistry](https://github.com/psviderski/unregistry)
- ability to push and store multi-platform images
The system gracefully handles machines without containerd support and provides clear error messages when required features aren't available.
## Improvements
- `uc ls` now displays the `IMAGE` column showing which container image(s) each service is running
- Service containers now receive `UNCLOUD_MACHINE_ID` environment variable with the machine ID they are running on
- Updated Docker and Compose Go dependencies to latest versions for better compatibility
## Bug fixes
- Fixed panic in Docker when pushing images without authentication
- Fixed error handling when removing non-existent services
## Changelog
* 2d361d3ee66778a16e80c183095b52a6be1c7a68 Adding machine.service.internal dns entries (#123)
* a2c6cbe6333653eb8085f3c518c5fc3b78559edd chore(images): filter images by name with wildcard pattern using Docker filter
* 509c9eb7d3a5662fbcdc56d3b5012b3cccc5f58a chore(images): format platforms as pills, sort images by name
* 59074a275f99cbf201fbe2bf443e512e167221d1 chore(images): initialise Docker service with containerd client
* cce81ecaad37272ac7ef2fa59c60279c4d6c13bf chore(images): simplifies ListImages service, server, and client to only list Docker images and not directly access containerd
* e8b4dd0bd1961b5ad335659b5af71ea0fd0e87c6 chore(push): fail 'image push' when containerd image store not used on target machine
* 521ccf202681a273a2fd75cd368abcd97cb8aacb chore(push): run unregistry only if containerd image store enabled for docker
* 337c15de35c72b7d15bab2bda9547dd739e93a18 chore: Add node to Mise
* c6d18f5d49aa3b25e8db0665cfe2a2eda237df82 chore: NAME -> IMAGE column name
* 782f4cb20b764a1a19fe929056ec1cea58fc8740 chore: Update AI.md with instructions around tests and docs
* 977fdf3cc3a3ebd282134f2e45eb2b53f15d138a chore: add Proxy for proxing local connections to a remote TCP address using the dialer
* fa004d63bb8093c6dfd92a91e0d7f0fe15167d6e chore: add firewall rule to allow cluster machines to push to other machines unregistry
* e0d11a8abcf6e91963dd8e0678310257234bf301 chore: configure Docker to use containerd image store by default (closes #129)
* 458d282357da4e462c567beb82897f7168a7c037 chore: correct comment and add TODO to move machine resolution to grpc-proxy router
* bc6f2fd49d525c139ea199648ba2fee1c996d71b chore: fix docker client CreateContainerWithImagePull, add WaitPortPublished
* 3bac1e61b956ac521dbaab4df304d8d63cd0dd95 chore: go mod tidy
* fc3297c7b7b54199ebb43b94c5065dc174321b5e chore: go mod tidy
* bcc504b8ccecb21c78f220cc22ec6ea478d7aadc chore: internal Docker client PushImage
* 27bbbe71866f87022849cd56fe12120951b1cdb8 chore: internal docker package with handy PullImage and CreateContainerWithImagePull methods
* ae458d260f1d210643352a8f41eccc282c2703f3 chore: refactor duplication
* e0045c7570a391145c1278be710a7425e7409ac6 chore: refactor gRPC docker client
* 82fd9744bf56cdecd7b99c12f8aaea5ba4b2ddf9 chore: remove unused imports
* 2969b40ad42d0b2c6f58e269114853605fff123e chore: return a proxy dialer for SSH connections
* a217643ac966c17d813a26404efa403419519a33 chore: shorten socat proxy container progress message
* a30ed600b6fe7c74368f390e6f1d2402fb1df4be chore: update docker and compose Go dependencies to the latest versions
* 6d2e100d631c9ca53276a1b0e3283d157b6efdc6 feat(images): 'uc image ls' and 'uc images' (alias) commands to list images on machines
* 0fc5032b27f62ffa3a03323ffa8df07bc8ca9a3d feat(images): add IN USE column to highlight which images are used by any container
* 92975eec51bf5bf66d349acb68be1ce97f6f2cd4 feat(images): add gRPC proto ListImages
* cdff036935ea37424010394c84408e52372bb8d0 feat(images): gRPC client and server for ListImages
* fba03b3df7e074c877b14ad75d7155a359b3dc12 feat(images): list image platforms and do not group images by machine
* 1f9c2c873d937873826f5fc3d7dbdcff23413106 feat(images): list images filtered by name
* 684f0d38eee0a7cd303a2259c9d1e6d417bc965a feat(push): '--platform all' to push image to all machines in cluster
* ffed906cef37ee7b6071979424af0ee6965fb07b feat(push): 'image push' to single or multiple machines via unregistry proxy
* 332e7bca90e4264da89d464d21107221dc1e3625 feat(push): --platform flag to push a specific platform of a multi-platform image
* 9f6880b7016cf9b7d38d7b9a45d3784496b68f92 feat(push): stub for 'image push' command and Dialer interface for cluster connectors
* 63c4de512e162a343cd5c3f6e03085304251b274 feat: Initial support for Compose configs (#116)
* b6b82861183bfbdc1b3d084c7e3657fb22925923 feat: run embedded unregistry on machine IP in uncloudd daemon
* 3e804d9ecc7980a28a69308e5aa207154895a03b feat: set UNCLOUD_MACHINE_ID in service container ENV (#135)
* 60926f64cca362df7f77e83faba0b33c0f867690 feat: show IMAGE column when listing services (uc ls) #13
* 5aa85ab50186114b4c9a08cd12fd0f3b684d1fdf fix(push): always provide encoded empty auth config to work around panic in Docker
* 08f233c5b1f11259ddd327f0ac9bbd9ff4b9e810 fix: auto-detect containerd.sock path and conditionally start unregistry
* cd25b973ea59fd8fe802796d4157e63fbd142009 fix: docker client PullImage
* 1a1afece7d47b1e3bd0b83d0d52cfbde819be2f7 fix: e2e test rebind the registry port to unoccupied 5001
* 893ab1f9f5c78646d6531cc87a66cdb4d7e135bb fix: negotiate docker client API version in e2e test
* 20cf98d42ec3abbf5ed0743e96e0ba31a05479b5 fix: return an error if 'uc rm' tries to remove a service that doesn't exist
* 784d86d8e82bb1f9337cca38ea175f2eac78479e fix: test build for docker server
* 265042e2c84e8cb8f24b3e5cb0de2eac2f0c2d3f lint