feat(services): traefik routing overrides via allowlisted middleware labels (#64)

services.traefik_labels (jsonb) holds operator-defined Traefik
middlewares keyed 'middlewares.<name>.<type>[.<field>]', validated
against an allowlist at write time. edgeLabels (extracted from
createReplica) scopes each definition to the service router as
<router>-<name> and auto-attaches it to the router's middleware chain
after builtins. Router/service/provider-level keys are rejected.

Surfaces: create/update API fields, services create/update
--traefik-label (repeatable, key=value), MCP arg docs, OpenAPI +
regenerated types, service-page Access editor (Routing overrides
card + textarea).

Also marks three stale ROADMAP2 items shipped: notification producers
round-out, build-on-node (PR #60), mobile env/domains/scaling (PR #61).

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 23:47:25 +02:00
1 parent 4071ed2991
commit a4bb7ad559
14 files changed
+445 -63

No files matched your search

+12
View File
@@ -7080,6 +7080,10 @@ components:
type: array
items: { type: string }
description: Node tags required for remote placement — auto/spread only consider agents carrying every tag; re-resolved each reconcile. Mutually exclusive with an explicit node_id pin (read-only on responses when a pin is set).
traefik_labels:
type: object
additionalProperties: { type: string }
description: Extra Traefik middlewares defined for this service's router — keys 'middlewares.<name>.<type>[.<field>]' (e.g. 'middlewares.rl.ratelimit.average'), allowlist-validated; each defined middleware attaches to the router after builtins
public_url:
type: string
description: Computed public URL (published port or domain)
@@ -7181,6 +7185,10 @@ components:
type: array
items: { type: string }
description: Restrict remote placement to agents carrying every listed tag; mutually exclusive with an explicit pin or 'local'
traefik_labels:
type: object
additionalProperties: { type: string }
description: Extra Traefik middlewares on the service router — keys 'middlewares.<name>.<type>[.<field>]'; allowlist-validated
UpdateServiceRequest:
type: object
@@ -7277,6 +7285,10 @@ components:
type: array
items: { type: string }
description: Restrict remote placement to agents carrying every listed tag; [] clears. Mutually exclusive with a pin or 'local' — clear the pin first
traefik_labels:
type: object
additionalProperties: { type: string }
description: Replace the service's Traefik middleware overrides — keys 'middlewares.<name>.<type>[.<field>]'; {} clears
ServiceDomain:
type: object