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
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
secretKeyRefinstead ofenvFrom: secretRef), but the runner still ships all controller code.Proposal
Create separate Dockerfile targets (multi-stage) for each role:
task_runner.py,copilot_session.py,coding_engine.py,git_operations.py, Azure Storage SDK, and Copilot SDKBenefits
Acceptance Criteria
controllerandrunnertargets