Sample manifests
Samples are not deployable as written. Set an explicit verified compatible fork runtime digest, replace the bucket name with a dedicated bucket, create the referenced ServiceAccount with a runtime IAM identity, and use zone names in the storage region.
bucket-ordered
Section titled “bucket-ordered”Bucket fleet using the Ordered StatefulSet layout with deterministic highest-ordinal retirement, across two zones.
apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: ordered-bucket-example namespace: defaultspec: profile: Bucket bucketWorkload: Ordered replicas: 3 serviceAccountName: celld-runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 2 zones: [us-east-1a, us-east-1b]bucket
Section titled “bucket”Three-replica Bucket fleet spread strictly across three zones. The minimal starting point.
apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: bucket-example namespace: defaultspec: profile: Bucket replicas: 3 serviceAccountName: celld-runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c]capacity-external
Section titled “capacity-external”Ordered Bucket with an HPA targeting the CelldFleet /scale subresource; scale-in removes one member per step after survivor-capacity checks.
# External capacity mode: one HorizontalPodAutoscaler owns spec.replicas through# the CelldFleet /scale subresource. Never target the managed StatefulSet.apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: agents namespace: agents-prodspec: profile: Bucket bucketWorkload: Ordered # Scale-in checks survivor capacity for the highest ordinal only. replicas: 3 serviceAccountName: agents-celld storage: bucket: agents-prod-celld region: us-east-1 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] capacity: mode: External---apiVersion: autoscaling/v2kind: HorizontalPodAutoscalermetadata: name: agents namespace: agents-prodspec: scaleTargetRef: apiVersion: celld.eric.dev/v1alpha1 kind: CelldFleet name: agents minReplicas: 3 # never below placement.azCount; the CRD rejects lower writes maxReplicas: 30 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 60 behavior: scaleDown: stabilizationWindowSeconds: 600 policies: - type: Pods value: 1 periodSeconds: 120capacity-shadow
Section titled “capacity-shadow”A Bucket fleet with a capacity block in Shadow mode: recommendations are recorded and reported, nothing scales.
apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: bucket-example namespace: defaultspec: profile: Bucket replicas: 3 serviceAccountName: celld-runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] # Add this block to either profile. Collect observations before enabling ScaleOut. capacity: mode: Shadow minReplicas: 3 maxReplicas: 6 scaleOutStep: 1 sampleIntervalSeconds: 15 maxAgeSeconds: 45 scaleOutStabilizationSeconds: 30 scaleInStabilizationSeconds: 600 scaleOutCooldownSeconds: 300 scaleInCooldownSeconds: 900 provisioningTimeoutSeconds: 600export-bucket
Section titled “export-bucket”apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: export-bucket-example namespace: fleetsspec: profile: Bucket replicas: 3 # Replace with a fork release that ships change export; none does yet. runtimeImage: ghcr.io/ewhauser/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 serviceAccountName: runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] export: sink: Bucket classes: [Cart, Order] excludeTables: [Cart.audit_log] bucket: # Optional; the runtime ServiceAccount must be able to write it. name: replace-with-export-bucket flushMilliseconds: 10000 retentionDays: 30export-kafka
Section titled “export-kafka”apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: export-kafka-example namespace: fleetsspec: profile: Bucket replicas: 3 # v0.6.1-ewhauser.3 Kafka variant, built with export-kafka. runtimeImage: ghcr.io/ewhauser/celld@sha256:d880dae9f8e14d55740fbcf361d01e32cefca113b631a6e9cf99f5f1f1edbc4e serviceAccountName: runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] execution: # Room for the default 256 MiB export queue. memoryLimit: 2Gi export: sink: Kafka classes: [Cart, Order] kafka: brokers: - kafka-0.kafka.kafka.svc:9092 - kafka-1.kafka.kafka.svc:9092 - kafka-2.kafka.kafka.svc:9092 # Create it first, with max.message.bytes >= 1114112. topic: celld-changes retryMilliseconds: 30000 # librdkafka settings, one name=value per line. Every key of the # Secret is mounted under /etc/celld/export, so it can carry the CA: # security.protocol=SASL_SSL # sasl.mechanisms=SCRAM-SHA-512 # sasl.username=celld # sasl.password=... # ssl.ca.location=/etc/celld/export/ca.crt propertiesSecretKeyRef: name: kafka-client key: kafka.properties egress: podLabels: app.kubernetes.io/name: kafka namespace: kafkafleet-previews
Section titled “fleet-previews”Platform-owned shared storage and routing configuration with small independent preview runtimes.
# Existing application fleet with optional preview configuration.# The preview bucket and credentials are separate from this fleet's own storage.apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: development namespace: previewsspec: runtimeImage: ghcr.io/ewhauser/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 profile: Bucket replicas: 1 serviceAccountName: celld-runtime storage: bucket: development-application region: us-east-1 sizeGiB: 10 placement: azCount: 1 zones: [us-east-1a] mode: Relaxed previews: runtimeImage: ghcr.io/ewhauser/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 serviceAccountName: preview-runtime zone: us-east-1a storage: bucket: shared-previews region: us-east-1 # Omit endpoint to use AWS S3 with the ServiceAccount's identity. endpoint: url: http://preview-store.previews.svc:9000 credentialsSecretName: preview-store egress: namespace: previews podLabels: app.kubernetes.io/name: preview-store routing: baseDomain: previews.example.com scheme: https ingress: className: nginx tlsSecretName: previews-wildcard-tls source: namespace: ingress-nginx podLabels: app.kubernetes.io/component: controller # Defaults shown for capacity planning; these sections may be omitted. execution: cpuRequest: 25m memoryRequest: 64Mi memoryLimit: 256Mi maxResidentCells: 8 idleEvictSeconds: 30 scratch: request: 64Mi limit: 512Miistio-mesh
Section titled “istio-mesh”Bucket fleet in the Istio mesh under STRICT mTLS, with port 8080 left to your own AuthorizationPolicy, shown after the fleet.
apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: mesh-example namespace: fleetsspec: profile: Bucket replicas: 3 # Replace with the verified compatible fork digest. runtimeImage: ghcr.io/ewhauser/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 serviceAccountName: runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] # Members join the Istio mesh with a native sidecar and stay reachable under # STRICT mTLS. The operator must be in the mesh too (chart value # podLabels."sidecar.istio.io/inject": "true"). mesh: istio: controlPlaneNamespace: istio-system # Port 8080 callers are granted by your own AuthorizationPolicies. applicationAccess: Policies---# Your policy for the application port. The operator's mesh-example-mesh policy# already admits peers and the operator on 8081.apiVersion: security.istio.io/v1kind: AuthorizationPolicymetadata: name: mesh-example-clients namespace: fleetsspec: selector: matchLabels: celld.eric.dev/fleet: mesh-example action: ALLOW rules: - from: - source: principals: ["cluster.local/ns/apps/sa/web"] to: - operation: ports: ["8080"]maintenance-paused
Section titled “maintenance-paused”PersistentFleet with maintenance paused and a commented restart token, showing the request fields.
apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: maintenance-example namespace: fleetsspec: profile: PersistentFleet replicas: 3 maintenance: paused: true # Change restartToken to request a same-version restart after unpausing. # Strict placement must remain valid; small PersistentFleets need explicit downtime. # restartToken: maintenance-2026-09 # Use the same verified sha256 digest through a registry mirror when needed. # The mirrored image must be the qualified celld fork artifact. runtimeImage: 123456789012.dkr.ecr.us-east-1.amazonaws.com/cache/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 # There is no default compatible pin; omission blocks provisioning. serviceAccountName: runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 storageClassName: ebs-delete placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c]persistent
Section titled “persistent”Three-replica PersistentFleet on a Delete-policy CSI StorageClass with strict placement.
apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: persistent-example namespace: defaultspec: profile: PersistentFleet replicas: 3 serviceAccountName: celld-runtime storage: bucket: replace-with-another-dedicated-bucket region: us-east-1 storageClassName: ebs-delete sizeGiB: 10 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] mode: Strictpreview-seeded
Section titled “preview-seeded”A preview seeded from several Durable Objects; requires pool source authorization and a separately installed snapshot/import executor.
# Developer-owned selection for a pool with seeding configured.# Requires a compatible external celld snapshot/import executor; none is bundled.apiVersion: celld.eric.dev/v1alpha1kind: CelldPreviewmetadata: name: reproduce-checkout namespace: previewsspec: fleetRef: name: development source: feature/checkout-fix revision: replace-with-commit-sha ttlSeconds: 86400 seed: source: production alarms: Clear objects: - class: Cart id: cart-123 - class: Customer id: customer-456 - class: Inventory id: sku-789preview-store
Section titled “preview-store”Optional disposable shared MinIO store; replacing its Pod loses all preview data.
# Optional disposable shared store. Adapt capacity and placement to your cluster.# A lost Pod loses ALL preview data; use an existing retained store when needed.# Pre-create Secret preview-store with accessKeyId and secretAccessKey keys.# Create the shared-previews bucket before creating previews (see docs/previews.md).apiVersion: v1kind: ServiceAccountmetadata: name: preview-runtime namespace: previews---apiVersion: v1kind: Servicemetadata: name: preview-store namespace: previewsspec: selector: app.kubernetes.io/name: preview-store ports: - name: s3 port: 9000 targetPort: 9000---apiVersion: apps/v1kind: Deploymentmetadata: name: preview-store namespace: previewsspec: replicas: 1 strategy: type: Recreate selector: matchLabels: app.kubernetes.io/name: preview-store template: metadata: labels: app.kubernetes.io/name: preview-store spec: automountServiceAccountToken: false securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 seccompProfile: type: RuntimeDefault containers: - name: minio image: quay.io/minio/minio@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e args: [server, /data, --address, ':9000'] env: - name: MINIO_ROOT_USER valueFrom: secretKeyRef: name: preview-store key: accessKeyId - name: MINIO_ROOT_PASSWORD valueFrom: secretKeyRef: name: preview-store key: secretAccessKey ports: - name: s3 containerPort: 9000 readinessProbe: httpGet: path: /minio/health/ready port: s3 resources: requests: cpu: 100m memory: 256Mi ephemeral-storage: 1Gi limits: memory: 1Gi ephemeral-storage: 10Gi securityContext: allowPrivilegeEscalation: false capabilities: drop: [ALL] volumeMounts: - name: data mountPath: /data volumes: - name: data emptyDir: sizeLimit: 10Gi---# Runtime and in-cluster CI clients need this namespace and label.apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: preview-store namespace: previewsspec: podSelector: matchLabels: app.kubernetes.io/name: preview-store policyTypes: [Ingress] ingress: - from: - podSelector: matchExpressions: - key: celld.eric.dev/fleet-uid operator: Exists - podSelector: matchLabels: celld.eric.dev/preview-uploader: 'true' ports: - protocol: TCP port: 9000preview
Section titled “preview”A developer preview referencing a shared pool, with a unique URL and 24-hour lifetime.
# Developer-owned: all infrastructure settings come from the existing pool.apiVersion: celld.eric.dev/v1alpha1kind: CelldPreviewmetadata: name: pr-42 namespace: previewsspec: fleetRef: name: development source: feature/login revision: replace-with-commit-sha ttlSeconds: 86400routing-gateway
Section titled “routing-gateway”# Requires an existing edge controller; adapt hosts, source labels and bucket.apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: routed-example namespace: defaultspec: runtimeImage: ghcr.io/ewhauser/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 profile: Bucket bucketWorkload: Ordered replicas: 3 serviceAccountName: celld-runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 2 zones: [us-east-1a, us-east-1b] routing: hostnames: [app.example.com] gateway: name: public namespace: edge sectionName: https source: namespace: edge podLabels: app: public-gatewayrouting-ingress
Section titled “routing-ingress”# Requires an existing edge controller; adapt hosts, source labels and bucket.apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: routed-example namespace: defaultspec: runtimeImage: ghcr.io/ewhauser/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 profile: Bucket bucketWorkload: Ordered replicas: 3 serviceAccountName: celld-runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 2 zones: [us-east-1a, us-east-1b] routing: hostnames: [app.example.com] ingress: className: nginx tlsSecretName: app-tls annotations: cert-manager.io/cluster-issuer: letsencrypt source: namespace: ingress-nginx podLabels: app.kubernetes.io/component: controllertelemetry
Section titled “telemetry”apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: telemetry-example namespace: fleetsspec: profile: Bucket replicas: 3 # Replace with the verified compatible fork digest. runtimeImage: ghcr.io/ewhauser/celld@sha256:1c0d854cd2af39fa439f163d5b88a19c7bccefd25fe35e2c0e1f43b3d886f424 serviceAccountName: runtime storage: bucket: replace-with-dedicated-bucket region: us-east-1 sizeGiB: 10 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] telemetry: collectorURL: http://otel-collector.fleets.svc:4318 egress: podLabels: app: otel-collector sampler: parentbased_traceidratio samplerArg: "0.1" flushMilliseconds: 5000 flushBytes: 1048576 headersSecretKeyRef: name: otel-auth key: headersImmutable execution sizing and lifecycle budgets selected before creation.
# Per-fleet tuning. Every field is optional and immutable after creation; the# operator never rolls out a changed pod template. Values are starting points,# not capacity guarantees, and the capacity policy's thresholds are independent.apiVersion: celld.eric.dev/v1alpha1kind: CelldFleetmetadata: name: agents namespace: agents-prodspec: # Optional additional celld settings are immutable after fleet creation. # env: # - name: CELLD_LOG # value: debug # - name: CELLD_API_TOKEN # secretKeyRef: # name: runtime-auth # key: token profile: Bucket replicas: 3 serviceAccountName: agents-celld storage: bucket: agents-prod-celld region: us-east-1 sizeGiB: 20 placement: azCount: 3 zones: [us-east-1a, us-east-1b, us-east-1c] execution: cpuRequest: "2" cpuLimit: "2" memoryRequest: 4Gi memoryLimit: 4Gi maxResidentCells: 400 # replace with a measured safe cap for the application idleEvictSeconds: 60 lifecycle: shutdownSeconds: 120 # CELLD_SHUTDOWN_TOTAL_MS terminationGraceSeconds: 180 # must exceed shutdownSeconds by at least 5Experimental software for evaluation.Capabilities and limitations· Contribute