Skip to main content
Home Docs Kubernetes Quick Start

Kubernetes Quick Start

Run the full Cloud Health Office platform on Docker Desktop Kubernetes — the same architecture, namespaces, services, and manifests used in production on Azure AKS. No Azure account needed.

Docker Compose vs Kubernetes

The Docker Compose Quick Start is faster for API testing and claims adjudication. This guide gives you the full production-equivalent Kubernetes deployment — same namespace layout, DNS, secrets, ConfigMaps, and health probes as Azure AKS.

What You Get

ComponentCountNotes
Microservices25Claims, Members, Eligibility, Payments, FHIR, Appeals, Capitation, etc.
Portal1Blazor Server UI — same as portal.cloudhealthoffice.com
MongoDB1StatefulSet with persistent storage
Redis1Data-protection key store and caching
NamespacecloudhealthofficeMatches production layout

All services communicate over Kubernetes DNS (service-name.cloudhealthoffice) — identical to production.

Prerequisites

ToolHow to CheckInstall
Docker Desktop 4.x+docker --versiondocker.com
Kubernetes enabledkubectl cluster-infoDocker Desktop > Settings > Kubernetes > Enable
kubectlkubectl version --clientBundled with Docker Desktop
bash 4+bash --versionmacOS: brew install bash
curlcurl --versionPre-installed on macOS/Linux
jq (optional)jq --versionbrew install jq
Resource requirements

The full platform runs 25+ pods. Allocate at least 4 CPU cores and 8 GB memory in Docker Desktop (Settings > Resources). First build pulls .NET 8 SDK + runtime images — budget ~8 GB disk for images.

1. Enable Kubernetes in Docker Desktop

1

Turn on Kubernetes and verify the cluster

  1. Open Docker Desktop > Settings > Kubernetes
  2. Check Enable Kubernetes
  3. Click Apply & Restart — wait for the green indicator
# Verify context
kubectl config current-context
# Expected: docker-desktop

# Verify cluster
kubectl cluster-info
# Expected: Kubernetes control plane is running at https://127.0.0.1:6443

2. Configure Credentials (Optional)

2

Add real Azure AD and Stripe keys for full portal login

The deploy script works out of the box with stub values — all services start and API endpoints work. For real Azure AD sign-in and Stripe payments:

cp .env.local.example .env.local
# Edit .env.local with your Azure AD app registration and Stripe test keys

Without .env.local, the portal UI loads but Azure AD sign-in won’t work. API endpoints function normally with the X-Tenant-ID header.

3. Build & Deploy

3

One command deploys the entire platform

./scripts/deploy-local.sh

This builds Docker images for all 25 services + portal, creates the cloudhealthoffice namespace, deploys MongoDB and Redis, creates all Kubernetes secrets, seeds demo data, and deploys all microservices using the same k8s manifests as production.

First run: ~10–15 minutes (image builds). Subsequent runs: ~2 minutes.

FlagWhat it does
--skip-buildDeploy only (images already built)
--only-buildBuild images without deploying

Watch the rollout

In a separate terminal:

watch kubectl get pods -n cloudhealthoffice

All pods should reach Running / 1/1 Ready within 2–3 minutes after images are built.

4. Access the Platform

4

Port-forward to access services locally

Services run inside the cluster on ClusterIP. Use port-forwarding to reach them (open each in a separate terminal, or append & to background):

# Portal (Blazor Server UI)
kubectl port-forward -n cloudhealthoffice svc/portal 8080:80

# Core API services
kubectl port-forward -n cloudhealthoffice svc/claims-service 5001:80
kubectl port-forward -n cloudhealthoffice svc/benefit-plan-service 5002:80
kubectl port-forward -n cloudhealthoffice svc/member-service 5003:80
kubectl port-forward -n cloudhealthoffice svc/provider-service 5004:80
kubectl port-forward -n cloudhealthoffice svc/eligibility-service 5005:80
kubectl port-forward -n cloudhealthoffice svc/payment-service 5006:80

# MongoDB (for direct access)
kubectl port-forward -n cloudhealthoffice svc/mongodb 27017:27017
ServiceLocal URL
Portalhttp://localhost:8080
Claims API + Swaggerhttp://localhost:5001/swagger
Benefit Plans / Adjudicationhttp://localhost:5002/swagger
Membershttp://localhost:5003/swagger
Providershttp://localhost:5004/swagger
Eligibilityhttp://localhost:5005/swagger
Paymentshttp://localhost:5006/swagger

5. Seed Demo Data & Test Adjudication

5

Run the full claims lifecycle end-to-end

After port-forwarding Claims (5001) and Benefit Plan (5002):

CLAIMS_URL=http://localhost:5001 \
BENEFIT_URL=http://localhost:5002 \
./scripts/seed-local.sh --tenant demo

This seeds NCCI edits, creates a benefit plan, submits a claim, runs adjudication, executes a payment batch, and downloads an 835 ERA file — the complete claims lifecycle.

For a step-by-step walkthrough with individual curl commands, see the Docker Quick Start guide (steps 3–7 work identically after port-forwarding).

6. Verify System Health

6

Check pod status and health endpoints

# All pods
kubectl get pods -n cloudhealthoffice

# All services
kubectl get svc -n cloudhealthoffice

# Portal logs
kubectl logs -n cloudhealthoffice -l app=portal --tail=50

# Claims service logs
kubectl logs -n cloudhealthoffice -l app=claims-service --tail=50

# Find errors across all services
kubectl logs -n cloudhealthoffice --all-containers --tail=20 | grep -i error
You're running production-equivalent Kubernetes!

You now have the same 25-service microservices architecture running locally that powers portal.cloudhealthoffice.com in production. Same namespace, same DNS, same manifests, same health probes.

How This Matches Production

AspectLocal (Docker Desktop)Production (Azure AKS)
Namespacecloudhealthofficecloudhealthoffice
Service DNSsvc.cloudhealthofficesvc.cloudhealthoffice
K8s manifestsSame files, imagePullPolicy patchedAlways (pulls from ACR)
Container port80808080
SecretsLocal stubs via deploy-local.shAzure Key Vault
DatabaseMongoDB StatefulSet (single node)Azure Cosmos DB (MongoDB API)
RedisSingle podAzure Cache for Redis
Ingress / TLSNone (port-forward)NGINX + cert-manager + Let's Encrypt
Replicas1 per service2+ with HPA autoscaling
Image registryLocal Docker daemonAzure ACR / GitHub GHCR

Common Tasks

Rebuild and redeploy a single service

# Rebuild just the claims service
docker build -t choacrhy6h2vdulfru6.azurecr.io/cloudhealthoffice-claims-service:latest \
  -f src/services/claims-service/Dockerfile .

# Restart the deployment to pick up the new image
kubectl rollout restart deployment/claims-service -n cloudhealthoffice
kubectl rollout status deployment/claims-service -n cloudhealthoffice

Connect to MongoDB

kubectl port-forward -n cloudhealthoffice svc/mongodb 27017:27017

# In another terminal:
mongosh "mongodb://admin:localdev123@localhost:27017/?authSource=admin"

Scale a service

kubectl scale deployment/claims-service -n cloudhealthoffice --replicas=3

Apply a manifest change

kubectl apply -f src/services/claims-service/k8s/claims-service-deployment.yaml

Troubleshooting

Pods stuck in ImagePullBackOff

Images are built locally but the manifest says imagePullPolicy: Always. The deploy script patches this automatically. If you applied a manifest manually:

kubectl patch deployment claims-service -n cloudhealthoffice \
  -p '{"spec":{"template":{"spec":{"containers":[{"name":"claims-service","imagePullPolicy":"IfNotPresent"}]}}}}'

Pods in CrashLoopBackOff

Usually a missing secret or MongoDB not ready yet:

# Check what's failing
kubectl describe pod -n cloudhealthoffice -l app=claims-service
kubectl logs -n cloudhealthoffice -l app=claims-service --previous

# Verify secrets exist
kubectl get secrets -n cloudhealthoffice

MongoDB not starting

kubectl describe statefulset mongodb -n cloudhealthoffice
kubectl logs -n cloudhealthoffice mongodb-0

If PVC issues on Docker Desktop: Settings > Kubernetes > Reset Kubernetes Cluster.

Port-forward drops

Port-forwards disconnect when pods restart. Re-run the command, or use kubefwd for automatic forwarding.

Services can't reach each other

kubectl run -n cloudhealthoffice dns-test --rm -it --image=busybox -- \
  nslookup claims-service.cloudhealthoffice

Docker Desktop running slow

Increase resources in Docker Desktop > Settings > Resources: 4+ CPU cores, 8+ GB memory.

Tear Down

Stop everything (keep data)

kubectl delete namespace cloudhealthoffice

Data in MongoDB PVCs persists. Re-run ./scripts/deploy-local.sh --skip-build to bring it back.

Full reset (delete everything including data)

kubectl delete namespace cloudhealthoffice
docker volume prune -f

Next Steps