TazLab K8s: Image Automation Detail
Level 3 (Detail) — All image automation pipelines with exact tag patterns and commit strategy.
Concept
Flux image automation watches container registries (Docker Hub / GHCR) for new tags matching a pattern, then automatically commits the updated image reference back to the tazlab-k8s repository. This closes the loop between CI/CD build and GitOps reconciliation.
Architecture
GitHub Action (push) → Docker Hub (tag) → Flux ImageRepository (poll 1m) → ImagePolicy (select latest) → ImageUpdateAutomation (commit to git) → Flux reconcile (deploy)
Each pipeline is defined in infrastructure/automation/<app>/automation.yaml as three Flux CRDs:
- ImageRepository: polls the registry every 1 minute
- ImagePolicy: selects the latest tag (numerical asc or semver — see pipeline inventory)
- ImageUpdateAutomation: commits the updated image reference to
master
Pipeline Inventory
1. hugo-blog
| Resource | Name | Details |
|---|---|---|
| ImageRepository | hugo-blog | tazzo/tazlab-blog, poll 1m |
| ImagePolicy | hugo-blog | Tag: ^blog-(?P<value>[0-9]+)-.*$, numerical asc |
| ImageUpdateAutomation | hugo-blog | Commit: chore: self-update hugo-blog image [skip ci] |
| Update path | ./apps/base/hugo-blog | |
| Update strategy | Setters |
Upstream: blog-src repository → GitHub Action publish.yml → Docker Hub tazzo/tazlab-blog.
2. hugo-wiki
| Resource | Name | Details |
|---|---|---|
| ImageRepository | hugo-wiki | tazzo/tazlab-wiki, poll 1m |
| ImagePolicy | hugo-wiki | Tag: ^wiki-(?P<value>[0-9]+)-.*$, numerical asc |
| ImageUpdateAutomation | hugo-wiki | Commit: chore: self-update hugo-wiki image [skip ci] |
| Update path | ./apps/base/hugo-wiki | |
| Update strategy | Setters |
Upstream: wiki.tazlab.net repository → GitHub Action publish.yml → Docker Hub tazzo/tazlab-wiki.
3. mnemosyne-mcp
| Resource | Name | Details |
|---|---|---|
| ImageRepository | mnemosyne-mcp | tazzo/mnemosyne-mcp, poll 1m |
| ImagePolicy | mnemosyne-mcp | Tag: ^mcp-(?P<value>[0-9]+)-.*$, numerical asc |
| ImageUpdateAutomation | mnemosyne-mcp | Commit: chore: self-update mnemosyne-mcp image [skip ci] |
| Update path | ./apps/base/mnemosyne-mcp | |
| Update strategy | Setters |
Upstream: mnemosyne-mcp-server repository → GitHub Action publish.yml → Docker Hub tazzo/mnemosyne-mcp.
4. homepage
| Resource | Name | Details |
|---|---|---|
| ImageRepository | homepage | ghcr.io/gethomepage/homepage, poll 1m |
| ImagePolicy | homepage | Semver range >=2.1.2 (pinned floor after the 2026-08 outage) |
| ImageUpdateAutomation | homepage | Commit: chore: self-update homepage image [skip ci] |
| Update path | ./infrastructure/instances/homepage | |
| Update strategy | Setters |
Upstream: upstream gethomepage/homepage releases (public GHCR image — no GitHub Action needed). The automation already bumped the live image from the manual pin v2.1.2 to v2.2.0 (infrastructure/instances/homepage/homepage.yaml:146).
Note the model variance: this pipeline is the only one using GHCR + semver; the other six use Docker Hub + numerical run numbers.
Homepage context: see Homepage Dashboard — the 2026-08 outage that motivated this pipeline.
5. teaching
| Resource | Name | Details |
|---|---|---|
| ImageRepository | teaching | tazzo/tazlab-teaching, poll 1m |
| ImagePolicy | teaching | Tag ^teaching-(?P<value>[0-9]+)-.*$, numerical asc |
| ImageUpdateAutomation | teaching | Commit chore: self-update teaching image [skip ci] |
| Update path | ./apps/base/teaching | |
| Update strategy | Setters |
6. ambrogio-site
| Resource | Name | Details |
|---|---|---|
| ImageRepository | ambrogio-site | tazzo/tazlab-ambrogio-site, poll 1m |
| ImagePolicy | ambrogio-site | Tag ^ambrogio-site-(?P<value>[0-9]+)-.*$, numerical asc |
| ImageUpdateAutomation | ambrogio-site | Commit chore: self-update ambrogio-site image [skip ci] |
| Update path | ./apps/base/ambrogio-site | |
| Update strategy | Setters |
7. halloween
| Resource | Name | Details |
|---|---|---|
| ImageRepository | halloween | tazzo/tazlab-halloween, poll 1m, public |
| ImagePolicy | halloween | Tag ^halloween-(?P<value>[0-9]+)-.*$, numerical asc, extract: $value |
| ImageUpdateAutomation | halloween | Commit chore: self-update halloween image [skip ci] |
| Update path | ./apps/base/halloween | |
| Update strategy | Setters |
Upstream: halloween.tazlab.net → GitHub Action → Docker Hub tazzo/tazlab-halloween.
The first deployment and the scanner/audio fix were delivered automatically:
halloween-1-eec65ff… → halloween-2-c91765e…; the pod rolled with Recreate and an
emptyDir reset (no PVC).
Tag Pattern Reference
| App | Pattern | Extracted value | Example tag |
|---|---|---|---|
| hugo-blog | ^blog-(?P<value>[0-9]+)-.*$ | run_number | blog-45-a1b2c3d |
| hugo-wiki | ^wiki-(?P<value>[0-9]+)-.*$ | run_number | wiki-12-e4f5g6h |
| mnemosyne-mcp | ^mcp-(?P<value>[0-9]+)-.*$ | run_number | mcp-42-7ba6c96d |
| teaching | ^teaching-(?P<value>[0-9]+)-.*$ | run_number | teaching-28-3897107a |
| ambrogio-site | ^ambrogio-site-(?P<value>[0-9]+)-.*$ | run_number | ambrogio-site-15-73a64e10 |
| halloween | ^halloween-(?P<value>[0-9]+)-.*$ | run_number | halloween-2-c91765e1 |
| homepage | semver >=2.1.2 | semver release | v2.2.0 |
Homepage uses Flux semver ordering (policy.semver.range: '>=2.1.2'); the other six use numerical: order: asc — Flux selects the tag with the highest run number.
Markers in Deployment
Each Deployment manifest has an image line like:
image: tazzo/tazlab-blog:blog-45-a1b2c3d # {"$imagepolicy": "flux-system:hugo-blog"}
The comment after the # is the Flux setter marker. It tells ImageUpdateAutomation which exact line to update. The format is:
# {"$imagepolicy": "<namespace>:<policy-name>"}
Commit Behavior
- Bot:
fluxcdbot@tazlab.net - Branch:
master(direct push) - Message:
chore: self-update <app> image [skip ci] - Strategy: Setters (regex replacement of the image tag after the marker comment)
See Also
- Parent hub: tazlab-k8s
- Sibling topic: Image Automation
- Sibling details: Flux Kustomizations Detail
- Reference: Image Policy Example