Docker & Kubernetes

View as MarkdownOpen in Claude

Dockerfile

Each language has a different Dockerfile. Choose the one matching your SDK language.

1FROM python:3.11-slim
2
3WORKDIR /app
4
5## Install dependencies
6COPY requirements.txt .
7RUN pip install --no-cache-dir -r requirements.txt
8
9## Copy application
10COPY . .
11
12## Create non-root user
13RUN useradd -m appuser && chown -R appuser:appuser /app
14USER appuser
15
16## Expose port
17EXPOSE 3000
18
19## Run with uvicorn
20CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "3000", "--workers", "4"]

Application entry point (Python)

1## app.py
2from signalwire import AgentBase
3
4class MyAgent(AgentBase):
5 def __init__(self):
6 super().__init__(name="my-agent")
7 self.add_language("English", "en-US", "rime.spore")
8 self.prompt_add_section("Role", "You are a helpful assistant.")
9
10agent = MyAgent()
11app = agent._app

Building and running

$## Build image
$docker build -t signalwire-agent .
$
$## Run container
$docker run -d \
> -p 3000:3000 \
> -e SWML_BASIC_AUTH_USER=myuser \
> -e SWML_BASIC_AUTH_PASSWORD=mypassword \
> --name agent \
> signalwire-agent
$
$## View logs
$docker logs -f agent
$
$## Stop container
$docker stop agent

Docker Compose

1## docker-compose.yml
2version: '3.8'
3
4services:
5 agent:
6 build: .
7 ports:
8 - "3000:3000"
9 environment:
10 - SWML_BASIC_AUTH_USER=${SWML_BASIC_AUTH_USER}
11 - SWML_BASIC_AUTH_PASSWORD=${SWML_BASIC_AUTH_PASSWORD}
12 - SWML_PROXY_URL_BASE=${SWML_PROXY_URL_BASE}
13 restart: unless-stopped
14 healthcheck:
15 test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
16 interval: 30s
17 timeout: 10s
18 retries: 3
19
20 nginx:
21 image: nginx:alpine
22 ports:
23 - "443:443"
24 - "80:80"
25 volumes:
26 - ./nginx.conf:/etc/nginx/nginx.conf:ro
27 - ./certs:/etc/ssl/certs:ro
28 depends_on:
29 - agent
30 restart: unless-stopped

Run with:

$docker-compose up -d

Kubernetes deployment

Kubernetes manifests are language-agnostic. The only difference is the Docker image referenced and any build steps. Use the appropriate Dockerfile from the section above to build your image, then deploy with the same manifests regardless of language.

LanguageImage Build Command
Pythondocker build -f Dockerfile.python -t your-registry/agent:latest .
TypeScriptdocker build -f Dockerfile.ts -t your-registry/agent:latest .

Deployment manifest

1## deployment.yaml
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: signalwire-agent
6 labels:
7 app: signalwire-agent
8spec:
9 replicas: 3
10 selector:
11 matchLabels:
12 app: signalwire-agent
13 template:
14 metadata:
15 labels:
16 app: signalwire-agent
17 spec:
18 containers:
19 - name: agent
20 image: your-registry/signalwire-agent:latest
21 ports:
22 - containerPort: 3000
23 env:
24 - name: SWML_BASIC_AUTH_USER
25 valueFrom:
26 secretKeyRef:
27 name: agent-secrets
28 key: auth-user
29 - name: SWML_BASIC_AUTH_PASSWORD
30 valueFrom:
31 secretKeyRef:
32 name: agent-secrets
33 key: auth-password
34 resources:
35 requests:
36 memory: "256Mi"
37 cpu: "250m"
38 limits:
39 memory: "512Mi"
40 cpu: "500m"
41 livenessProbe:
42 httpGet:
43 path: /health
44 port: 3000
45 initialDelaySeconds: 10
46 periodSeconds: 30
47 readinessProbe:
48 httpGet:
49 path: /health
50 port: 3000
51 initialDelaySeconds: 5
52 periodSeconds: 10

Service manifest

1## service.yaml
2apiVersion: v1
3kind: Service
4metadata:
5 name: signalwire-agent
6spec:
7 selector:
8 app: signalwire-agent
9 ports:
10 - protocol: TCP
11 port: 80
12 targetPort: 3000
13 type: ClusterIP

Ingress manifest

1## ingress.yaml
2apiVersion: networking.k8s.io/v1
3kind: Ingress
4metadata:
5 name: signalwire-agent
6 annotations:
7 nginx.ingress.kubernetes.io/ssl-redirect: "true"
8 cert-manager.io/cluster-issuer: "letsencrypt-prod"
9spec:
10 ingressClassName: nginx
11 tls:
12 - hosts:
13 - agent.example.com
14 secretName: agent-tls
15 rules:
16 - host: agent.example.com
17 http:
18 paths:
19 - path: /
20 pathType: Prefix
21 backend:
22 service:
23 name: signalwire-agent
24 port:
25 number: 80

Secrets

1## secrets.yaml
2apiVersion: v1
3kind: Secret
4metadata:
5 name: agent-secrets
6type: Opaque
7stringData:
8 auth-user: your-username
9 auth-password: your-secure-password

Kubernetes architecture

Kubernetes architecture diagram showing pods, services, ingress, and SignalWire Cloud.
Kubernetes Architecture

Deploying to Kubernetes

$## Create secrets
$kubectl apply -f secrets.yaml
$
$## Deploy application
$kubectl apply -f deployment.yaml
$kubectl apply -f service.yaml
$kubectl apply -f ingress.yaml
$
$## Check status
$kubectl get pods -l app=signalwire-agent
$kubectl get svc signalwire-agent
$kubectl get ingress signalwire-agent
$
$## View logs
$kubectl logs -f -l app=signalwire-agent
$
$## Scale deployment
$kubectl scale deployment signalwire-agent --replicas=5

Horizontal Pod Autoscaler

1## hpa.yaml
2apiVersion: autoscaling/v2
3kind: HorizontalPodAutoscaler
4metadata:
5 name: signalwire-agent
6spec:
7 scaleTargetRef:
8 apiVersion: apps/v1
9 kind: Deployment
10 name: signalwire-agent
11 minReplicas: 2
12 maxReplicas: 10
13 metrics:
14 - type: Resource
15 resource:
16 name: cpu
17 target:
18 type: Utilization
19 averageUtilization: 70

Multi-architecture builds

1## Build for multiple architectures
2FROM --platform=$TARGETPLATFORM python:3.11-slim
3
4## ... rest of Dockerfile

Build with:

$docker buildx build --platform linux/amd64,linux/arm64 -t your-registry/agent:latest --push .

Container best practices

Security

  • Run as non-root user
  • Use minimal base images (slim, alpine)
  • Scan images for vulnerabilities
  • Don’t store secrets in images

Performance

  • Use multi-stage builds to reduce image size
  • Layer dependencies efficiently
  • Set appropriate resource limits

Reliability

  • Add health checks
  • Use restart policies
  • Configure proper logging
  • Set graceful shutdown handling