USMAN’S INSIGHTS
AI ARCHITECT
  • Home
  • About
  • Thought Leadership
  • Book
Press / Contact
USMAN’S INSIGHTS
AI ARCHITECT
⌘F
HomeBook
HomeBookThe Production Choreography: Why Deploying Everything at Once Will Destroy Your Stack
Previous Chapter
Cloud Load Balancer DNS
Next Chapter
Production Secrets Configuration
AI NOTICE: This is the table of contents for the SPECIFIC CHAPTER only. It is NOT the global sidebar. For all chapters, look at the main navigation.

On this page

55 sections

Progress0%
1 / 55

Muhammad Usman Akbar Entity Profile

Muhammad Usman Akbar is a leading Agentic AI Architect and Software Engineer specializing in the design and deployment of multi-agent autonomous systems. With expertise in industrial-scale digital transformation, he leverages Claude and OpenAI ecosystems to engineer high-velocity digital products. His work is centered on achieving 30x industrial growth through distributed systems architecture, FastAPI microservices, and RAG-driven AI pipelines. Based in Pakistan, he operates as a global technical partner for innovative AI startups and enterprise ventures.

USMAN’S INSIGHTS
AI ARCHITECT

Transforming businesses into autonomous AI ecosystems. Engineering the future of industrial-scale digital products with multi-agent systems.

30X Growth
AI-First
Innovation

Navigation

  • Home
  • Book
  • About
  • Contact
Let's Collaborate

Have a Project in Mind?

Let's build something extraordinary together. Transform your vision into autonomous AI reality.

Start Your Transformation

© 2026 Muhammad Usman Akbar. All rights reserved.

Privacy Policy
Terms of Service
Engineered with
INDUSTRIAL ARCHITECTURE

Deploying Task API to DOKS

Your DOKS cluster is provisioned, kubectl is connected, and you understand DNS and Load Balancers. Now comes the moment you've been building toward: deploying your complete Task API stack to production infrastructure.

This isn't a single kubectl apply command. A production deployment involves multiple components that depend on each other. Dapr must exist before your application can use its sidecars. The Ingress controller must have an external IP before cert-manager can validate domain ownership. Certificates must be issued before HTTPS works.

The order matters. Get it wrong, and you'll spend hours debugging why pods are stuck in CrashLoopBackOff or why certificates show "pending" forever.


The Deployment Sequence: Order Matters

Think of deploying to production like building a house. You can't install windows before framing the walls, and you can't run electricity before the walls are up. Cloud Kubernetes deployments follow the same logic:

text
Step 1: Dapr (distributed application runtime) │ ▼ Step 2: Traefik Ingress Controller (receives traffic) │ ▼ Step 3: cert-manager (issues TLS certificates) │ ▼ Step 4: Task API Helm Release (your application) │ ▼ Step 5: Verification (prove it works)

Why this order?

  • Dapr first: Your Task API pods need Dapr sidecars injected. If Dapr isn't installed, pods fail to start.
  • Traefik second: cert-manager needs an Ingress controller to handle HTTP-01 challenges. No Ingress = no certificate validation.
  • cert-manager third: You want HTTPS from the start. Installing cert-manager before your app means certificates are ready when traffic arrives.
  • Task API last: Now all dependencies exist. Your app deploys with sidecars, routes through Ingress, and serves over HTTPS.

Step 1: Initialize Dapr on DOKS

Dapr provides service invocation, state management, and pub/sub for your Task API. On a cloud cluster, initialization is nearly identical to local—but the resources run on cloud nodes.

Install Dapr CLI (if not already installed)

bash
# macOS brew install dapr/tap/dapr-cli # Linux wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash

Output:

Specification
Dapr CLI installed successfully. CLI version: 1.13.0 Runtime version: n/a

Initialize Dapr on the Cluster

bash
dapr init -k --wait

Output:

Specification
Making the jump to hyperspace... Note: To install Dapr using Helm, see here: https://docs.dapr.io/operations/hosting/kubernetes/kubernetes-deploy/#install-with-helm Deploying the Dapr control plane to your cluster... Success! Dapr has been installed to namespace dapr-system. To verify, run `dapr status -k`

Verify Dapr Installation

bash
dapr status -k

Output:

text
NAME NAMESPACE HEALTHY STATUS REPLICAS VERSION AGE CREATED dapr-sentry dapr-system True Running 1 1.13.0 45s 2024-12-23 14:30:00 dapr-operator dapr-system True Running 1 1.13.0 45s 2024-12-23 14:30:00 dapr-placement-server dapr-system True Running 1 1.13.0 45s 2024-12-23 14:30:00 dapr-sidecar-injector dapr-system True Running 1 1.13.0 45s 2024-12-23 14:30:00 dapr-dashboard dapr-system True Running 1 1.13.0 45s 2024-12-23 14:30:00

All five Dapr components are running. The sidecar-injector will automatically add Dapr sidecars to pods with the correct annotations.


Step 2: Install Traefik Ingress Controller

Traefik will receive all incoming traffic and route it to your services. On DOKS, installing Traefik creates a DigitalOcean Load Balancer automatically.

Add Traefik Helm Repository

bash
helm repo add traefik https://traefik.github.io/charts helm repo update

Output:

Specification
"traefik" has been added to your repositories Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "traefik" chart repository Update Complete.

Install Traefik

bash
helm install traefik traefik/traefik \ --namespace traefik \ --create-namespace \ --set service.type=LoadBalancer

Output:

Specification
NAME: traefik LAST DEPLOYED: Mon Dec 23 14:32:15 2024 NAMESPACE: traefik STATUS: deployed REVISION: 1

Wait for External IP

The Load Balancer takes 2-3 minutes to provision. Wait for it:

bash
kubectl get svc -n traefik --watch

Output (after ~2 minutes):

Specification
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE traefik Load Balancer 10.245.100.42 143.198.123.45 80:31024/TCP,443:30812/TCP 2m15s

When EXTERNAL-IP shows an IP address (not <pending>), your Load Balancer is ready. Note this IP—you'll need it for DNS.

Configure DNS

Point your domain to the Load Balancer IP:

TypeNameValue
Atasks143.198.123.45
A*.tasks143.198.123.45

If you don't have a domain, use nip.io for testing: tasks.143.198.123.45.nip.io automatically resolves to that IP.


Step 3: Install cert-manager

cert-manager automates TLS certificate issuance from Let's Encrypt. Once installed, it watches for Certificate resources and automatically obtains and renews certificates.

Install cert-manager

bash
helm repo add jetstack https://charts.jetstack.io helm repo update helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --set installCRDs=true

Output:

Specification
NAME: cert-manager LAST DEPLOYED: Mon Dec 23 14:35:22 2024 NAMESPACE: cert-manager STATUS: deployed REVISION: 1

Verify cert-manager Pods

bash
kubectl get pods -n cert-manager

Output:

Specification
NAME READY STATUS RESTARTS AGE cert-manager-7b8c5c5d5c-xb9j8 1/1 Running 0 45s cert-manager-cainjector-6b8c5c5d5c-k2m4p 1/1 Running 0 45s cert-manager-webhook-5b8c5c5d5c-j9n3l 1/1 Running 0 45s

Create ClusterIssuer for Let's Encrypt

Create a file letsencrypt-prod.yaml:

yaml
apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: your-email@example.com privateKeySecretRef: name: letsencrypt-prod-account-key solvers: - http01: ingress: class: traefik

Apply it:

bash
kubectl apply -f letsencrypt-prod.yaml

Output:

Specification
clusterissuer.cert-manager.io/letsencrypt-prod created

Verify ClusterIssuer

bash
kubectl get clusterissuer

Output:

Specification
NAME READY AGE letsencrypt-prod True 30s

Ready: True means cert-manager can communicate with Let's Encrypt.


Step 4: Deploy Task API with Helm

Now deploy your Task API using the Helm chart from an earlier Chapter. Create a production values file that includes your domain and TLS configuration.

Create Production Values File

Create values-doks.yaml:

yaml
# Task API Production Configuration for DOKS replicaCount: 2 image: repository: your-registry/task-api tag: "v1.0.0" pullPolicy: Always # Enable Dapr sidecar injection dapr: enabled: true appId: "task-api" appPort: 8000 service: type: ClusterIP port: 8000 # Ingress with TLS ingress: enabled: true className: "traefik" annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" traefik.ingress.kubernetes.io/router.entrypoints: "websecure" hosts: - host: tasks.yourdomain.com paths: - path: / pathType: Prefix tls: - secretName: task-api-tls hosts: - tasks.yourdomain.com # Cloud-appropriate resources resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m" # Health checks livenessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 5 periodSeconds: 5 # Environment configuration env: - name: LOG_LEVEL value: "INFO" - name: ENVIRONMENT value: "production"

Deploy Task API

bash
helm install task-api ./task-api-chart \ -f values-doks.yaml \ --namespace default

Output:

Specification
NAME: task-api LAST DEPLOYED: Mon Dec 23 14:40:33 2024 NAMESPACE: default STATUS: deployed REVISION: 1

Wait for Pods

bash
kubectl get pods --watch

Output:

Specification
NAME READY STATUS RESTARTS AGE task-api-6f8c5c5d5c-abc12 2/2 Running 0 45s task-api-6f8c5c5d5c-def34 2/2 Running 0 45s

Notice 2/2 READY—that's your application container plus the Dapr sidecar.


Step 5: Verify the Complete Stack

Check Certificate Status

bash
kubectl get certificate

Output:

Specification
NAME READY SECRET AGE task-api-tls True task-api-tls 2m

READY: True means Let's Encrypt issued your certificate successfully.

If READY shows False, check the Certificate resource:

bash
kubectl describe certificate task-api-tls

Look for events explaining why issuance failed (usually DNS not propagated or HTTP challenge failed).

Check Ingress

bash
kubectl get ingress

Output:

Specification
NAME CLASS HOSTS ADDRESS PORTS AGE task-api traefik tasks.yourdomain.com 143.198.123.45 80, 443 3m

Test HTTPS Endpoint

bash
curl https://tasks.yourdomain.com/health

Output:

json
{"status": "healthy", "version": "1.0.0"}

Your Task API is running on production infrastructure with:

  • Dapr sidecar for distributed capabilities
  • Traefik handling ingress traffic
  • Let's Encrypt TLS certificate
  • Cloud Load Balancer distributing traffic

Full Stack Verification Commands

Run these to confirm everything is operational:

bash
# Dapr components dapr status -k # Traefik with Load Balancer kubectl get svc -n traefik # cert-manager kubectl get pods -n cert-manager # Certificate issued kubectl get certificate # Task API pods with sidecars kubectl get pods # Ingress routing kubectl get ingress # Final test curl -v https://tasks.yourdomain.com/health

Expected successful output pattern:

text
< HTTP/2 200 < content-type: application/json < {"status": "healthy", "version": "1.0.0"}

What You've Deployed

Your production stack now includes:

ComponentPurposeNamespace
DaprService mesh, state, pub/subdapr-system
TraefikIngress controller, Load Balancertraefik
cert-managerAutomatic TLS certificatescert-manager
Task APIYour application with Dapr sidecardefault

This is the same architecture pattern used by production AI services. The components are loosely coupled—you can upgrade Traefik without touching your application, or switch cert-manager issuers without redeploying.


Common Issues and Diagnosis

Certificate Stuck on "Pending"

Symptom:

text
kubectl get certificate NAME READY SECRET AGE task-api-tls False task-api-tls 10m

Diagnosis:

bash
kubectl describe certificate task-api-tls kubectl get challenges

Common causes:

  • DNS not propagated (wait 5 minutes, check with dig tasks.yourdomain.com)
  • Ingress class mismatch (verify traefik in both ClusterIssuer and Ingress)
  • HTTP-01 challenge failing (check Load Balancer firewall allows port 80)

Pods Show 1/2 Ready

Symptom: Task API pods show 1/2 instead of 2/2

Diagnosis:

bash
kubectl logs task-api-xyz -c daprd

Common causes:

  • Dapr not initialized (run dapr init -k)
  • Missing Dapr annotations in deployment
  • Dapr sidecar-injector not running

No External IP on Load Balancer

Symptom: kubectl get svc -n traefik shows <pending> for EXTERNAL-IP

Diagnosis:

  • Check DigitalOcean dashboard for Load Balancer quota
  • Verify cluster has --auto-upgrade or correct DOKS version
  • Check node capacity (Load Balancer needs healthy nodes)

Try With AI

Challenge: Deploy your Task API to DOKS with the full production stack.

Part 1: Deployment Planning

Open Claude Code in your project directory and ask:

text
I have a DOKS cluster running. Help me plan the deployment order for Task API with Dapr, Traefik Ingress, and cert-manager TLS.

Record the deployment sequence AI suggests. Does it match the order in this lesson? Note any differences.

Part 2: Configuration Review

AI will suggest default configurations. Evaluate them:

  • Does the Helm values file include my domain?
  • Is TLS enabled with Let's Encrypt production issuer?
  • Are resource requests/limits appropriate for DOKS?

Tell AI your specific requirements:

text
My domain is tasks.example.com, I want production Let's Encrypt certificates, and 512Mi memory limit for Task API pods.

Watch how AI adapts the configuration to your constraints.

Part 3: Deployment Execution

Execute the deployment commands AI provides. Watch for:

  • Dapr pods appearing in dapr-system namespace
  • Traefik LoadBalancer getting EXTERNAL-IP
  • cert-manager Certificate showing Ready: True

If any step fails, share the error with AI:

text
The Traefik service shows EXTERNAL-IP as <pending> after 5 minutes. Here's kubectl describe svc traefik -n traefik output: [paste output]

Part 4: Troubleshooting Together

If your certificate isn't issued after deployment:

text
My Certificate shows Ready: False. Here's the output of kubectl describe certificate task-api-tls: [paste output]

Work through the diagnosis together. What did AI suggest checking? What did you discover about your configuration?

Part 5: Verification

Test your production endpoint:

bash
curl https://tasks.yourdomain.com/health

Ask yourself:

  • What improved through iteration with AI?
  • Which configuration details did you refine based on AI suggestions?
  • What did you correct when AI made assumptions that didn't match your setup?

Safety Note: Never share API tokens, passwords, or other secrets in prompts. Configure secrets through Kubernetes Secrets, not environment variables in values files.


Reflect on Your Skill

Test your multi-cloud-deployer skill against what you learned:

Test Your Skill

text
Using my multi-cloud-deployer skill, generate a complete deployment script for DOKS that includes Dapr, Traefik, cert-manager, and a Helm application with TLS.

Identify Gaps

Does your skill:

  • Know the correct deployment order (Dapr -> Traefik -> cert-manager -> app)?
  • Include wait commands between dependent components?
  • Generate ClusterIssuer for Let's Encrypt?
  • Add TLS annotations to Ingress configuration?

Improve Your Skill

If gaps exist:

text
My multi-cloud-deployer skill is missing full stack deployment patterns. Update it to include: - Deployment sequence for DOKS (Dapr, Traefik, cert-manager) - Wait commands between component installations - ClusterIssuer configuration for Let's Encrypt - Helm values with TLS annotations for Traefik Ingress

By the end of this chapter, your skill handles complete production deployments—not just cluster provisioning.