A lightweight, set-and-forget container update daemon for Docker.
Orbitd monitors your containers and automatically updates them when new images are available, preserving all configuration, networks, volumes, and labels.
- Zero Configuration: Works out of the box with sensible defaults
- Automatic Rollback: Restores previous container on update failure
- Flexible Policies: Digest-only or semantic versioning (patch/minor/major)
- Label Control: Opt-in or opt-out specific containers
- Image Cleanup: Removes old images after successful updates
- Compose Friendly: Updated containers stay in sync, so
docker compose upwon't recreate them
services:
orbitd:
image: ghcr.io/mizuchilabs/orbitd:latest
container_name: orbitd
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sockThat's it. Orbitd will check all containers every 12 hours (by default) and update them when new digests are available.
You can also run orbitd in docker swarm (it must run on a manager node):
services:
orbitd:
image: ghcr.io/mizuchilabs/orbitd:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
replicas: 1
placement:
constraints:
- node.role == managerAll settings are optional. Configure via environment variables or CLI flags:
| Environment Variable | CLI Flag | Default | Description |
|---|---|---|---|
ORBITD_SCHEDULE |
--schedule |
@every 12h |
Cron schedule or interval descriptor |
ORBITD_POLICY |
--policy |
digest |
Update policy (see below) |
ORBITD_CLEANUP |
--cleanup |
true |
Remove replaced images after updates |
ORBITD_REQUIRE_LABEL |
--require-label |
false |
Only update labeled containers |
ORBITD_DEBUG |
--debug |
false |
Enable verbose logging |
Orbitd uses standard cron expressions or interval descriptors for scheduling updates via the ORBITD_SCHEDULE environment variable (or --schedule flag).
Examples:
@every 12h- Run every 12 hours from start (Default)@every 30m- Run every 30 minutes0 3 * * *- Run daily at 3:00 AM0 0 * * 0- Run weekly on Sunday at midnight
| Policy | Behavior | Example |
|---|---|---|
digest |
Same tag, new digest (default) | nginx:1.25 → latest build |
patch |
Patch versions only | 1.2.3 → 1.2.9 |
minor |
Minor + patch versions | 1.2.3 → 1.9.0 |
major |
Any newer version | 1.2.3 → 2.0.0 |
Semver policies require version tags. Non-version tags fall back to digest updates.
Only tags written like the current one are considered:
16.2-alpinemoves to16.4-alpinebut never to16.4-bookworm, a floating1.25moves to1.26but not to a pinned1.25.3, andv1.2.0only matches otherv-prefixed tags. Prereleases (-rc.1,-beta, …) are only picked when the current tag is one.
- Containers are recreated with their explicit configuration (env, labels, command, volumes, networks, …). Defaults inherited from the old image are dropped so the new image's defaults apply.
- Containers are stopped using their own stop timeout (
--stop-timeout/stop_grace_period). - Anonymous volumes are carried over to the new container.
- Containers sharing another container's network (
network_mode: container:…/service:…) are reattached when that container is updated. - Containers pinned to a digest (
image@sha256:…) are left alone. - In swarm mode, services are updated through the swarm manager. Swarm task containers are never touched by a standalone instance, e.g. one running on a worker node.
By default, orbitd monitors all running containers. Use ORBITD_REQUIRE_LABEL=true to switch to opt-in mode, where only containers with orbitd.enable=true are monitored.
You can also override the update policy per container with orbitd.policy:
services:
# Opt-in to monitoring (required when require-label is enabled)
app:
image: myapp:latest
labels:
- "orbitd.enable=true"
# Override policy for this container
api:
image: myapi:1.0.0
labels:
- "orbitd.enable=true"
- "orbitd.policy=minor"
# Not monitored (no label)
database:
image: postgres:15docker run -d \
--name orbitd \
--restart unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/mizuchilabs/orbitd:latestDownload from releases and run:
./orbitd startOrbitd uses Docker's default credential chain to authenticate with private registries. To pull images from private repositories, mount your Docker config file into the orbitd container:
services:
orbitd:
image: ghcr.io/mizuchilabs/orbitd:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/youruser/.docker/config.json:/root/.docker/config.json:roThis config file is populated by running docker login on your host. Orbitd will use these credentials for both image tag discovery and pulling.
Apache 2.0 License - see LICENSE for details