feat(scheduling): node tags + service placement_tags affinity (#58)

Operator-set node labels (node_agents.tags) gate which nodes a service
may schedule onto: services.placement_tags requires every listed tag.
auto and spread filter eligible agents by tags; tags are re-evaluated
each reconcile so retagging a node re-spreads replicas. Pin + tags and
local + tags rejected; empty array clears the requirement.

Surfaces: --placement-tags on services create/update, nodes update
--tags, MCP args, OpenAPI, node-detail tag editor, service-detail
placement-tags input.

Generated with [Devin](https://devin.ai)

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomáš DvořákandDevin authored and GitHub committed 2026-10-09 18:11:19 +02:00
1 parent 9de586f177
commit 4458de56b0
23 files changed
+475 -37

No files matched your search

+9
View File
@@ -152,6 +152,15 @@ containr services update <id> --replicas 4 --spread # replica i → node[i %
containr services update <id> --spread=false # back to single placement
```
Constrain `auto`/`spread` placement to nodes carrying operator tags —
`nodes update` labels a node, `--placement-tags` requires every listed tag
(mutually exclusive with a pin; an empty value clears the requirement):
```bash
containr nodes update <id> --tags gpu,eu-west
containr services update <id> --placement-tags gpu # only gpu nodes are eligible
```
Remote nodes run registry-pulled images only — git builds, domains
(Traefik lives on the host), and sleep detection stay local. Start,
stop, restart, redeploy, and delete all fan out to the pinned node's