Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.emergence.ai/llms.txt

Use this file to discover all available pages before exploring further.

Package and Deploy

The Quickstart deploys a single-component solution. This page extends to multi-component (api + worker + scheduler + agent…), per-environment overlays, image-publish workflows, and where ArgoCD picks up from there.

Single vs multi-component

em-service (v0.0.16) is the base chart for one deployable workload — one Deployment, one Service, one set of probes. Solutions that need more than one workload include em-service multiple times as subchart dependencies, each with a unique alias. Read top-down: one umbrella chart per solution; one em-service instance per workload (api / worker / scheduler / agent); per-environment values overlay-merge with the defaults. Add a fourth alias and you’ve added a fourth deployable component — no other moving parts change. See em-service Chart › Using as a subchart for the canonical reference.

Multi-component layout

A typical “API + worker” solution:
charts/<solution>/Chart.yaml
apiVersion: v2
name: <solution>
description: <solution> on CRAFT
type: application
version: 0.1.0
appVersion: "0.1.0"
dependencies:
  - name: em-service
    alias: api
    version: 0.0.16
    repository: oci://ghcr.io/emergenceai/em-charts
  - name: em-service
    alias: worker
    version: 0.0.16
    repository: oci://ghcr.io/emergenceai/em-charts
  - name: em-service
    alias: scheduler   # optional Prefect / cron component
    version: 0.0.16
    repository: oci://ghcr.io/emergenceai/em-charts
Each alias has its own values block in values.yaml:
charts/<solution>/values.yaml
api:
  image:
    repository: ghcr.io/<org>/<solution>-api
    tag: 0.1.0
  service:
    type: ClusterIP
    port: 8000
  env:
    LOG_LEVEL: "INFO"
  envVars:
    - name: DATABASE_URL
      valueFrom: { secretKeyRef: { name: <solution>-secrets, key: database-url } }
  readinessProbe: { httpGet: { path: /healthz, port: 8000 } }
  livenessProbe:  { httpGet: { path: /healthz, port: 8000 } }
  autoscaling:
    enabled: true
    minReplicas: 2
    maxReplicas: 10
    targetCPUUtilizationPercentage: 70

worker:
  image:
    repository: ghcr.io/<org>/<solution>-worker
    tag: 0.1.0
  service:
    enabled: false   # workers don't expose HTTP
  env:
    LOG_LEVEL: "INFO"
    QUEUE_NAME: "<solution>-jobs"
  envVars:
    - name: DATABASE_URL
      valueFrom: { secretKeyRef: { name: <solution>-secrets, key: database-url } }

scheduler:
  image:
    repository: ghcr.io/<org>/<solution>-scheduler
    tag: 0.1.0
  service:
    enabled: false
  replicaCount: 1   # singleton — never scale schedulers horizontally

Per-environment overlays

Use one values.yaml for shared defaults, plus values.<env>.yaml overlays for things that change between environments (image tags, replica counts, host names, log levels). Apply with helm -f:
helm upgrade --install <solution> ./charts/<solution> \
  --namespace em-<solution> --create-namespace \
  --values ./charts/<solution>/values.yaml \
  --values ./charts/<solution>/values.dev.yaml \
  --wait --timeout 5m
Example dev overlay:
charts/<solution>/values.dev.yaml
api:
  image: { tag: dev }
  replicaCount: 1
  autoscaling: { enabled: false }
  env: { LOG_LEVEL: "DEBUG" }
worker:
  image: { tag: dev }
  replicaCount: 1
Production overlay (just the deltas):
charts/<solution>/values.prod.yaml
api:
  image: { tag: 1.4.7 }
  autoscaling: { minReplicas: 3, maxReplicas: 20 }
  ingress:
    enabled: true
    className: nginx
    hosts:
      - host: <solution>.example.com
        paths: [{ path: /, pathType: Prefix }]
worker:
  image: { tag: 1.4.7 }
  replicaCount: 4

Build and publish images

Per-component, multi-stage Dockerfile (one image per workload). Use the same Dockerfile parametrized via --target if your components share a build base; or one Dockerfile per component if they diverge significantly.
# Build
docker build -t ghcr.io/<org>/<solution>-api:1.4.7    --target api    .
docker build -t ghcr.io/<org>/<solution>-worker:1.4.7 --target worker .

# Login (whatever registry you use)
docker login ghcr.io -u <user> -p $GITHUB_TOKEN

# Publish
docker push ghcr.io/<org>/<solution>-api:1.4.7
docker push ghcr.io/<org>/<solution>-worker:1.4.7
For private registries, configure imagePullSecrets in values.yaml:
api:
  imagePullSecrets: [{ name: ghcr-pull }]
worker:
  imagePullSecrets: [{ name: ghcr-pull }]

Versioning

Keep the Helm chart version and the image tag independent:
WhatBumped when
Chart version (in Chart.yaml)Chart structure changes (added/removed/renamed values, alias changes)
appVersionDefault app version this chart targets — informational
Image tag (in values.yaml)Application code changes
Use semver for both. See Helm › Upgrades for the upgrade policy (which chart-version bumps are breaking, how to roll back, etc.).

Deploy

Local

helm dependency update ./charts/<solution>
helm upgrade --install <solution> ./charts/<solution> \
  --namespace em-<solution> --create-namespace \
  -f ./charts/<solution>/values.yaml \
  -f ./charts/<solution>/values.dev.yaml \
  --wait --timeout 5m

kubectl -n em-<solution> get pods -w
Verify all components are running and probes are passing.

CI/CD

For automated deploys, use whatever CI/CD your team prefers; the chart itself is environment-agnostic.

Air-gapped deployments

If the target cluster has no internet access (some customer environments), pre-stage:
  1. The chart tarball (helm pull oci://ghcr.io/emergenceai/em-charts/em-service --version 0.0.16)
  2. All component images (docker save | docker load on the air-gapped side)
  3. The pull-secret pointing at the customer’s internal registry

Verification

# Chart renders cleanly with the production overlay
helm template <solution> ./charts/<solution> \
  -f ./charts/<solution>/values.yaml \
  -f ./charts/<solution>/values.prod.yaml | head -50

# All declared components have running pods
kubectl -n em-<solution> get deployments
kubectl -n em-<solution> get pods

# Image tags match what you intended to deploy
kubectl -n em-<solution> get pods -o jsonpath='{.items[*].spec.containers[*].image}' | tr ' ' '\n' | sort -u

Next steps

em-service Chart

Full values reference for the base chart.

Helm › Configuration

Platform-wide chart configuration.

Helm › Upgrades

Upgrade and rollback policy.

Starter templates

Pre-built scaffolds for common solution shapes.