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.

Quickstart: Hello Solution

By the end of this tutorial you will have a FastAPI service running in a local Kubernetes cluster, packaged as a Helm chart that wraps the platform’s em-service base chart, and reachable by curl. Total time: 30 minutes or less. If it takes longer, that’s a guide bug — please report via the 👎 thumbs at the bottom of this page.
This tutorial is self-contained: every prerequisite, command, and config snippet is in this page. You do not need access to any internal repository to follow it.

Prerequisites

Install these tools. Versions are floors, not pins — newer is fine.
ToolVersionPurpose
Docker24+Container runtime for Kind
Kind0.20+Local Kubernetes cluster
kubectl1.28+Kubernetes CLI
Helm3.13+Package manager for Kubernetes
uv0.4+Python project manager
brew install docker kind kubectl helm uv

What you’ll build

A solution called hello-solution with one component (api) that exposes:
  • GET /healthz{"status":"ok"} for k8s probes
  • GET /echo?msg=... → echoes the message back
The image is built locally and loaded into Kind (no registry needed). The Helm chart wraps em-service v0.0.16 with alias: api, so you’ll see how multi-component solutions extend (just add another alias).

Steps

1

Create the project layout

Pick a working directory and scaffold these files:
hello-solution/
├── packages/api/
│   ├── pyproject.toml
│   └── src/api/
│       └── main.py
├── Dockerfile
└── charts/hello-solution/
    ├── Chart.yaml
    └── values.yaml
mkdir -p hello-solution/packages/api/src/api hello-solution/charts/hello-solution
cd hello-solution
2

Write the FastAPI app

from fastapi import FastAPI

app = FastAPI(title="hello-solution")

@app.get("/healthz")
async def healthz() -> dict[str, str]:
    return {"status": "ok"}

@app.get("/echo")
async def echo(msg: str = "hi") -> dict[str, str]:
    return {"echo": msg}
3

Write the Dockerfile

A multi-stage build keeps the runtime image small.
Dockerfile
FROM python:3.12-slim AS build
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY packages/api/pyproject.toml packages/api/pyproject.toml
COPY packages/api/src packages/api/src
RUN uv pip install --system --no-cache-dir ./packages/api

FROM python:3.12-slim
COPY --from=build /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=build /usr/local/bin/uvicorn /usr/local/bin/uvicorn
EXPOSE 8000
CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000"]
4

Write the Helm chart

The chart declares one em-service subchart, aliased as api. The platform’s em-service (v0.0.16) handles Deployment, Service, probes, env vars — you only configure your image and ports. To add a worker later, you’d add another em-service entry with alias: worker and configure it under that alias key in values.yaml. See em-service Chart for the full values reference.
apiVersion: v2
name: hello-solution
description: A minimal CRAFT solution
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
5

Create a Kind cluster and load your image

# Create cluster
kind create cluster --name hello-solution

# Build and load image
docker build -t hello-solution-api:dev .
kind load docker-image hello-solution-api:dev --name hello-solution
kind load docker-image makes your local image available inside the cluster without a registry.
6

Install the chart

helm dependency update ./charts/hello-solution
helm upgrade --install hello-solution ./charts/hello-solution \
  --namespace em-hello-solution --create-namespace \
  --wait --timeout 5m
First install pulls em-service from ghcr.io/emergenceai/em-charts (this is a public registry; no auth needed).
7

Smoke-test it

kubectl port-forward -n em-hello-solution svc/hello-solution-api 8000:8000 &

curl -s "http://localhost:8000/healthz" | jq .
# {"status":"ok"}

curl -s "http://localhost:8000/echo?msg=ship%20it" | jq .
# {"echo":"ship it"}
If both calls succeed, you have shipped your first CRAFT solution.
8

Tear down

kill %1 2>/dev/null  # stop port-forward
helm uninstall hello-solution -n em-hello-solution
kubectl delete namespace em-hello-solution
kind delete cluster --name hello-solution

What you just did

You wrapped a 25-line FastAPI app in a Helm chart that depends on the platform’s em-service base chart, deployed it to a namespace named em-<solution> (the platform convention), and reached it via port-forward. You did not configure auth, secrets, storage, or LLMs yet — those are the next how-tos:

Register a solution

Make this naming + namespace pattern systematic.

Authenticate users

Protect /echo with JWT validation.

Manage secrets

Wire a secret-backed env var into your chart.

Local development

Loop faster with docker-compose + hot reload.