Unkey

Routing Service

Atomic ingress route and gateway configuration management

Routing Service

The RoutingService manages atomic ingress route assignments.

Location: go/apps/ctrl/workflows/routing/ Proto: go/proto/hydra/v1/routing.proto Key: project_id

Why Separate Service?

Ingress route and gateway operations are the critical section of deployments:

  • Must be atomic - both succeed or both fail
  • Must be serialized per project to prevent race conditions
  • Should not block non-routing operations (like building containers)

By separating routing, we:

  • Allow multiple deployments to build in parallel
  • Serialize only the sensitive routing mutations
  • Provide clear boundaries for concurrency control

Operations

AssignIngressRoutes

flowchart TD Start([AssignIngressRoutes]) --> LoopRoutes{For Each Route} LoopRoutes --> FindRoute[Find or Create Ingress Route] FindRoute --> NextRoute NextRoute --> LoopRoutes LoopRoutes --> UpdateDeployment[Update Deployment ID] UpdateDeployment --> End([Return Success]) style UpdateDeployment fill:#e1f5fe

Creates or reassigns ingress routes to a deployment:

  1. For each ingress route ID: update the deployment ID
  2. Routes are pre-created with hostnames and sticky behavior
  3. This operation simply points them to the new deployment
  4. Per-tenant gateways handle the actual traffic routing

Implementation: go/apps/ctrl/workflows/routing/assign_ingress_routes_handler.go

Ingress Route Sticky Levels:

  • BRANCH: Branch-level (e.g., main.domain.com)
  • ENVIRONMENT: Environment-level (e.g., staging.domain.com)
  • LIVE: Production domain (e.g., domain.com)

Per-Tenant Gateway Architecture

With the new per-tenant gateway model:

  1. Each environment has its own gateway instances
  2. Ingress routes point to deployments within an environment
  3. Gateway configuration is managed at the environment level
  4. This provides better isolation and scaling characteristics

Local Domain Filtering

Hostnames with .local or .test TLDs, or localhost/127.0.0.1 are typically excluded from production routing since they're for local development only.

On this page