Skip to content

chore: split controller and task runner into separate slim container images #289

@peteroden

Description

@peteroden

Context

The controller (orchestrator) and task runner currently share a single container image — only the entrypoint command differs. This means the runner image includes controller-only dependencies (FastAPI, webhook handling, Jira client, GitLab poller, etc.) that it never uses.

PR #288 already enforces credential isolation at the Kubernetes level (explicit secretKeyRef instead of envFrom: secretRef), but the runner still ships all controller code.

Proposal

Create separate Dockerfile targets (multi-stage) for each role:

  • controller image: Full image with FastAPI, webhook, poller, orchestrator, executors
  • runner image: Slim image with only task_runner.py, copilot_session.py, coding_engine.py, git_operations.py, Azure Storage SDK, and Copilot SDK

Benefits

  • Smaller runner image → faster KEDA scale-up (less pull time)
  • Reduced attack surface — runner has no webhook/API code
  • Clearer dependency boundaries between controller and runner
  • Easier to reason about what code runs where

Acceptance Criteria

  • Multi-stage Dockerfile with controller and runner targets
  • Runner image excludes FastAPI, uvicorn, Jira client, GitLab poller
  • Helm chart uses separate image refs for controller deployment and runner scaledjob
  • CI builds and pushes both images
  • E2E tests pass with split images

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions