Initial implementation: package-updater v1 #1

Merged
shcizo merged 27 commits from feat/initial-implementation into main 2026-05-22 11:59:39 +00:00
Showing only changes of commit 9832b2b190 - Show all commits
@@ -50,7 +50,7 @@ Watchtower remains in place for third-party images that the user does not build
3. Service validates token (constant-time compare). 3. Service validates token (constant-time compare).
4. Service lists Docker containers (running + stopped), filters by: 4. Service lists Docker containers (running + stopped), filters by:
- Image name match (tag-agnostic) - Image name match (tag-agnostic)
- Opt-in label `se.enocsson.auto-update=true` - Opt-in label `se.shcizo.auto-update=true`
5. For each match, reads Compose's built-in labels to find `working_dir`, `config_files`, `service`, `project`. 5. For each match, reads Compose's built-in labels to find `working_dir`, `config_files`, `service`, `project`.
6. Path safety check: refuse jobs whose `working_dir` is not inside `STACKS_ROOT`. 6. Path safety check: refuse jobs whose `working_dir` is not inside `STACKS_ROOT`.
7. Deduplicates `(project, service, config_files)` and enqueues one job per unique tuple. 7. Deduplicates `(project, service, config_files)` and enqueues one job per unique tuple.
@@ -161,7 +161,7 @@ Case-sensitive. No wildcards or regex (YAGNI).
### 5.3 Opt-in filter ### 5.3 Opt-in filter
Container must have label `se.enocsson.auto-update=true`. Anything else (`false`, missing, other value) is silently excluded. Container must have label `se.shcizo.auto-update=true`. Anything else (`false`, missing, other value) is silently excluded.
### 5.4 Compose label extraction ### 5.4 Compose label extraction
@@ -210,7 +210,7 @@ When the service receives an update whose image matches its own running containe
A container is eligible for update only if it has both: A container is eligible for update only if it has both:
- An image name matching the request, AND - An image name matching the request, AND
- The opt-in label `se.enocsson.auto-update=true`. - The opt-in label `se.shcizo.auto-update=true`.
Both gates are independent. Compromising either alone does not allow an attacker to trigger an update. Both gates are independent. Compromising either alone does not allow an attacker to trigger an update.
@@ -244,7 +244,7 @@ services:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
- /home/shcizo/self-hosted:/home/shcizo/self-hosted:ro - /home/shcizo/self-hosted:/home/shcizo/self-hosted:ro
labels: labels:
- "se.enocsson.auto-update=true" - "se.shcizo.auto-update=true"
networks: networks:
- proxy - proxy
healthcheck: healthcheck:
@@ -426,7 +426,7 @@ All configuration is via environment variables.
| `PORT` | no | `8080` | HTTP listen port. | | `PORT` | no | `8080` | HTTP listen port. |
| `LOG_LEVEL` | no | `info` | `debug`/`info`/`warn`/`error`. | | `LOG_LEVEL` | no | `info` | `debug`/`info`/`warn`/`error`. |
| `UPDATE_TIMEOUT` | no | `5m` | Per-job timeout. Go duration string. | | `UPDATE_TIMEOUT` | no | `5m` | Per-job timeout. Go duration string. |
| `OPT_IN_LABEL` | no | `se.enocsson.auto-update` | Label name to check (allows renaming without rebuild). Value must equal `"true"`. | | `OPT_IN_LABEL` | no | `se.shcizo.auto-update` | Label name to check (allows renaming without rebuild). Value must equal `"true"`. |
## 13. Repository Layout (planned) ## 13. Repository Layout (planned)