175 lines
3.5 KiB
Markdown
175 lines
3.5 KiB
Markdown
# docker-updater
|
|
|
|
`docker-updater` is a small Go daemon that monitors **running Docker containers** and automatically **updates their images** on a configurable cron schedule.
|
|
|
|
At a glance:
|
|
- Schedules update jobs using cron
|
|
- Compares **local image digest** vs **remote registry digest**
|
|
- If the image changed: **stop → pull → start** the container
|
|
|
|
> ⚠️ This tool does **not recreate containers** (no `docker compose up -d` behavior).
|
|
> It operates on the existing container ID. (for now)
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
- Cron-based image update scheduling
|
|
- Per-container configuration using Docker labels
|
|
- Digest-based update detection (safe and deterministic)
|
|
- Simple daemon, no database, no state persistence
|
|
- Written in Go, minimal dependencies
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
- Docker installed and running
|
|
- Access to Docker socket (`/var/run/docker.sock`)
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
### Build locally
|
|
|
|
```bash
|
|
make build
|
|
```
|
|
|
|
Binary will be available at:
|
|
|
|
```bash
|
|
./build/dockerupdater
|
|
```
|
|
|
|
## Usage
|
|
|
|
```bash
|
|
./dockerupdater -config ./config.json
|
|
```
|
|
|
|
### CLI options
|
|
|
|
| Flag | Description | Default |
|
|
| ---------- | ------------------- | --------------- |
|
|
| `-config` | Path to config file | `./config.json` |
|
|
| `-verbose` | Enable debug logs | `false` |
|
|
|
|
## Configuration
|
|
|
|
If the config file does not exist, default values are used.
|
|
|
|
### Example config.json
|
|
|
|
```json
|
|
{
|
|
"containers": {
|
|
"enabled": false,
|
|
"schedule": "* * * * *"
|
|
},
|
|
"daemon": {
|
|
"pull_interval": 2
|
|
}
|
|
}
|
|
```
|
|
|
|
### Configuration fields
|
|
|
|
```containers```
|
|
|
|
Global default configuration applied to all containers
|
|
(unless overridden by labels).
|
|
|
|
```containers.enabled``` (bool)
|
|
Enables or disables image updates by default.
|
|
|
|
```containers.schedule``` (string)
|
|
Cron expression (5-field format).
|
|
|
|
Examples:
|
|
|
|
*/5 * * * * → every 5 minutes
|
|
|
|
0 3 * * * → every day at 03:00
|
|
|
|
---
|
|
|
|
```daemon.pull_interval``` (uint)
|
|
|
|
Interval in seconds between daemon scans.
|
|
|
|
Used to detect:
|
|
|
|
- New containers
|
|
- Removed containers
|
|
- Container ID changes
|
|
|
|
> This does not control update frequency.
|
|
> Actual updates are triggered by cron schedules.
|
|
|
|
### Per-container configuration (Docker labels)
|
|
|
|
Containers can override global settings using Docker labels.
|
|
|
|
#### Supported labels
|
|
|
|
| Label | Description |
|
|
| -------------------------------------- | --------------------- |
|
|
| `com.thelilfrog.image.update.enable` | `"true"` or `"false"` |
|
|
| `com.thelilfrog.image.update.schedule` | Cron expression |
|
|
|
|
#### Example (```docker-compose.yml```)
|
|
|
|
```yaml
|
|
services:
|
|
myapp:
|
|
image: ghcr.io/acme/myapp:latest
|
|
labels:
|
|
com.thelilfrog.image.update.enable: "true"
|
|
com.thelilfrog.image.update.schedule: "*/10 * * * *"
|
|
```
|
|
|
|
## Running with Docker Compose
|
|
|
|
A minimal docker-compose.yml is provided:
|
|
|
|
```yaml
|
|
services:
|
|
runner:
|
|
build: ./
|
|
volumes:
|
|
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
|
```
|
|
|
|
## How updates work
|
|
|
|
1. Container is selected (enabled + valid digest)
|
|
2. Cron job triggers
|
|
3. Remote registry is queried
|
|
4. Digest comparison:
|
|
- Same → nothing happens
|
|
- Different → update
|
|
5. Update process:
|
|
- ```docker stop```
|
|
- ```docker pull```
|
|
- ```docker start```
|
|
|
|
## Known limitations
|
|
|
|
- Containers without RepoDigests are ignored
|
|
- Containers with multiple RepoDigests are ignored
|
|
- No container recreation
|
|
- No rollback mechanism
|
|
- Requires registry access for digest checks
|
|
|
|
## Logging
|
|
|
|
Uses structured JSON logs via slog.
|
|
|
|
Enable debug logs with:
|
|
|
|
```bash
|
|
-verbose
|
|
```
|