---
id: w1/m15/t001
title: `background_worker` type — no-port / no-ingress reconcile path
worker: worker1
status: done
estimate: 40m
depends_on: []
---

## Objective

Add Render's `background_worker` service type as a mechanism in `lego/types` + the operator: a worker runs the built image with no HTTP port, so its reconcile is a bare Deployment — the operator skips the Service, the Ingress, and the HTTP readiness/health gate entirely.

## Context

- The CRD types live in `lego/types/v1alpha1/*_types.go` (leaf module); after editing, run `make manifests generate` from `lego/operator/` and keep the generated output (deepcopy → `lego/types/v1alpha1/zz_generated.deepcopy.go`, CRD YAML → `lego/operator/config/crd/bases/`). Never hand-edit generated files.
- The Kubernetes reconcile is `lego/operator/internal/controller/` (the `kubernetes` runtime path builds Deployment/Service/Ingress). Today bex serves only `web_service`/`private_service`; a private service already has no Ingress, so worker is "private-service minus the Service and minus the HTTP health gate."
- Render's type name is `background_worker` (map the `App` spec's type field to it, tracking Render's vocabulary — cf. `docs/ADR006-bex-api.md` service `type`).

## Steps

1. Add a service-type field (or extend the existing one) on the `App` spec in `lego/types/v1alpha1` to carry `background_worker`; regenerate CRD + deepcopy from `lego/operator/`.
2. In the kubernetes reconcile, branch on type: for a worker, create/update only the Deployment; skip Service, Ingress, and the HTTP readiness probe / health-gate path.
3. Ensure status reflects a worker has no URL (no `serviceDetails.url`).

## Files

- `lego/types/v1alpha1/*_types.go` (+ regenerated `zz_generated.deepcopy.go`)
- `lego/operator/config/crd/bases/` (regenerated)
- `lego/operator/internal/controller/` (kubernetes reconcile)

## Acceptance criteria

- [x] An `App` with the worker type reconciles to a Deployment only — no Service, no Ingress, no HTTP health gate — and its status carries no URL.
- [x] `make manifests generate` output is committed and `make test` passes.

## Out of scope

- The create-surface `type` plumbing (t003) and the dashboard (t004).
- `cron_job` (t002) and static sites (deferred to `w1/012`).
