Fix docs
This commit is contained in:
parent
dbed46793a
commit
147fcd3c28
2 changed files with 61 additions and 26 deletions
|
|
@ -58,7 +58,7 @@ This is a Rust-based Docker Compose updater service that automatically updates i
|
||||||
|
|
||||||
- **Configuration-driven**: All behavior controlled through `config.yaml` including paths, schedules, registries, and update strategies.
|
- **Configuration-driven**: All behavior controlled through `config.yaml` including paths, schedules, registries, and update strategies.
|
||||||
- **Preserves formatting**: Uses line-by-line regex parsing rather than full YAML parsing to maintain comments and formatting.
|
- **Preserves formatting**: Uses line-by-line regex parsing rather than full YAML parsing to maintain comments and formatting.
|
||||||
- **Flexible update strategies**: Supports different version update approaches (latest patch of previous minor, latest patch, latest minor, latest).
|
- **Flexible update strategies**: Supports `LatestPatchOfPreviousMinor` (the highest patch of the newest available release line below the latest published line) and `Latest`. Both only apply targets newer than the current version.
|
||||||
- **Registry abstraction**: Generic registry client that works with multiple container registries.
|
- **Registry abstraction**: Generic registry client that works with multiple container registries.
|
||||||
- **Health monitoring**: Built-in health server for monitoring service status.
|
- **Health monitoring**: Built-in health server for monitoring service status.
|
||||||
|
|
||||||
|
|
@ -80,4 +80,4 @@ The system supports different update strategies defined in `config.rs`:
|
||||||
- Unit tests are embedded in each module using `#[cfg(test)]`
|
- Unit tests are embedded in each module using `#[cfg(test)]`
|
||||||
- Integration tests are in the `tests/` directory
|
- Integration tests are in the `tests/` directory
|
||||||
- Uses `tempfile` for testing file operations
|
- Uses `tempfile` for testing file operations
|
||||||
- Tests cover compose file parsing, image reference parsing, and scheduler creation
|
- Tests cover compose file parsing, image reference parsing, and scheduler creation
|
||||||
|
|
|
||||||
83
README.md
83
README.md
|
|
@ -64,8 +64,6 @@ services:
|
||||||
- GITHUB_TOKEN=${GITHUB_TOKEN}
|
- GITHUB_TOKEN=${GITHUB_TOKEN}
|
||||||
- RUST_LOG=info
|
- RUST_LOG=info
|
||||||
volumes:
|
volumes:
|
||||||
# Mount Docker socket (read-only for security)
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
# Mount compose files directory
|
# Mount compose files directory
|
||||||
- ./compose-files:/app/compose-files:rw
|
- ./compose-files:/app/compose-files:rw
|
||||||
# Mount configuration
|
# Mount configuration
|
||||||
|
|
@ -109,18 +107,42 @@ images if retries are exhausted. Warnings include the image and backend.
|
||||||
|
|
||||||
## Update Strategies
|
## Update Strategies
|
||||||
|
|
||||||
The service supports three intelligent update strategies, defaulting to the most conservative:
|
The service supports two update strategies, defaulting to `LatestPatchOfPreviousMinor`.
|
||||||
|
|
||||||
|
Both strategies consider only parseable registry tags with the same prefix and
|
||||||
|
suffix as the current tag. A selected target is applied only when its version is
|
||||||
|
strictly greater than the current version. Equal or older targets leave the
|
||||||
|
Compose file unchanged, so neither strategy downgrades an image.
|
||||||
|
|
||||||
### `LatestPatchOfPreviousMinor`
|
### `LatestPatchOfPreviousMinor`
|
||||||
- **Predictable**: Always updates to the latest patch of the previous minor version
|
|
||||||
- **Consistent Behaviour**: Never updates to the current latest minor
|
Selects the highest patch in the newest available release line below the latest
|
||||||
- **Example**: `1.5.3` → `1.4.8`
|
published line. A release line is a `(major, minor)` pair. Selection uses the
|
||||||
|
available registry versions; it does not subtract one from the installed minor
|
||||||
|
version. It can skip missing minor lines or cross a major-version gap. If there
|
||||||
|
is no older matching release line, no target is selected.
|
||||||
|
|
||||||
|
The following examples use illustrative registry tag sets:
|
||||||
|
|
||||||
|
| Current tag | Available matching registry tags | Selected target | Result |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `1.3.2` | `1.3.2`, `1.4.7`, `1.4.8`, `1.5.3` | `1.4.8` | Update to `1.4.8` |
|
||||||
|
| `1.4.8` | `1.3.2`, `1.4.7`, `1.4.8`, `1.5.3` | `1.4.8` | Unchanged: equal version |
|
||||||
|
| `1.5.3` | `1.3.2`, `1.4.7`, `1.4.8`, `1.5.3` | `1.4.8` | Unchanged: downgrade prevented |
|
||||||
|
| `2.1.0` | `2.1.0`, `2.3.5`, `2.5.2` | `2.3.5` | Update to `2.3.5`, skipping the missing `2.4` line |
|
||||||
|
| `4.0.15` | `4.0.15`, `4.0.19`, `5.14` | `4.0.19` | Update to `4.0.19` across the gap below `5.14` |
|
||||||
|
| `1.5.1` | `1.5.1`, `1.5.3` | None | Unchanged: only one release line available |
|
||||||
|
|
||||||
### `Latest`
|
### `Latest`
|
||||||
- **Aggressive**: Updates to the absolute latest available version
|
|
||||||
- **Cutting Edge**: Useful for development environments
|
Selects the highest available matching version, including major-version updates.
|
||||||
- **Example**: `1.5.3` → `2.1.0`
|
The same no-downgrade guard applies:
|
||||||
|
|
||||||
|
| Current tag | Available matching registry tags | Selected target | Result |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| `1.5.3` | `1.4.8`, `1.5.3`, `2.1.0` | `2.1.0` | Update to `2.1.0` |
|
||||||
|
| `2.1.0` | `1.4.8`, `1.5.3`, `2.1.0` | `2.1.0` | Unchanged: equal version |
|
||||||
|
| `2.1.0` | `1.4.8`, `1.5.3` | `1.5.3` | Unchanged: downgrade prevented |
|
||||||
|
|
||||||
## Advanced Version Handling
|
## Advanced Version Handling
|
||||||
|
|
||||||
|
|
@ -171,29 +193,31 @@ registries:
|
||||||
|
|
||||||
## Supported Image Formats
|
## Supported Image Formats
|
||||||
|
|
||||||
The updater handles various image naming conventions:
|
The updater handles various image naming conventions. These examples show image
|
||||||
|
references; update targets depend on the strategy and available registry tags as
|
||||||
|
described above.
|
||||||
|
|
||||||
```yaml
|
```text
|
||||||
# Standard Docker Hub images
|
# Standard Docker Hub images
|
||||||
nginx:1.21.0 → nginx:1.20.6
|
nginx:1.21.0
|
||||||
ubuntu:20.04 → ubuntu:18.04
|
ubuntu:24.10
|
||||||
|
|
||||||
# Namespaced images
|
# Namespaced images
|
||||||
bitnami/nginx:1.21.0 → bitnami/nginx:1.20.6
|
bitnami/nginx:1.21.0
|
||||||
library/postgres:13.7 → library/postgres:12.11
|
library/postgres:13.7
|
||||||
|
|
||||||
# Custom registries
|
# Custom registries
|
||||||
ghcr.io/user/app:v1.0.0 → ghcr.io/user/app:v0.9.5
|
ghcr.io/user/app:v1.0.0
|
||||||
registry.example.com/team/service:2.1.3 → registry.example.com/team/service:2.0.9
|
registry.example.com/team/service:2.1.3
|
||||||
|
|
||||||
# Complex versioning
|
# Complex versioning
|
||||||
nginx:1.21.0-alpine → nginx:1.20.6-alpine
|
nginx:1.21.0-alpine
|
||||||
postgres:13.7-bullseye → postgres:12.11-bullseye
|
postgres:13.7-bullseye
|
||||||
redis:v7.0.0-alpine3.16 → redis:v6.2.7-alpine3.16
|
redis:v7.0.0-alpine3.16
|
||||||
|
|
||||||
# Local development (typically ignored)
|
# Local development (ignored by the Quick Start ignore_images configuration)
|
||||||
localhost:5000/myapp:latest → [ignored by default]
|
localhost:5000/myapp:latest
|
||||||
127.0.0.1:8080/service:dev → [ignored by default]
|
127.0.0.1:8080/service:dev
|
||||||
```
|
```
|
||||||
|
|
||||||
## Health Monitoring & Observability
|
## Health Monitoring & Observability
|
||||||
|
|
@ -226,11 +250,22 @@ The service reports:
|
||||||
|
|
||||||
- **Non-Root Execution**: Designed to run as non-root user in containers
|
- **Non-Root Execution**: Designed to run as non-root user in containers
|
||||||
- **Minimal Attack Surface**: Alpine Linux base image with minimal packages
|
- **Minimal Attack Surface**: Alpine Linux base image with minimal packages
|
||||||
- **Read-Only Docker Socket**: Only requires read access to Docker socket
|
- **No Docker Daemon Access Required**: Queries registries and edits Compose files without a Docker socket mount
|
||||||
- **Secret Management**: All tokens provided via environment variables
|
- **Secret Management**: All tokens provided via environment variables
|
||||||
- **Input Validation**: Comprehensive validation of all configuration inputs
|
- **Input Validation**: Comprehensive validation of all configuration inputs
|
||||||
- **Error Sanitisation**: No sensitive information leaked in error messages
|
- **Error Sanitisation**: No sensitive information leaked in error messages
|
||||||
|
|
||||||
|
Mount only the Compose files to update and the configuration file. The updater
|
||||||
|
does not use the Docker daemon or restart running containers.
|
||||||
|
|
||||||
|
A `:ro` bind mount restricts filesystem changes to the socket path; it does not
|
||||||
|
make Docker API requests read-only. A process that can connect to the socket can
|
||||||
|
still send mutating requests. Docker daemon access can grant root authority on
|
||||||
|
the host; see [Docker's socket access guidance](https://docs.docker.com/engine/security/protect-access/).
|
||||||
|
If a future feature needs daemon access, enforce an API authorization boundary,
|
||||||
|
such as a [Docker authorization plugin](https://docs.docker.com/engine/extend/plugins_authorization/),
|
||||||
|
with an explicit policy limiting permitted requests.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Building from Source
|
### Building from Source
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue