Agent Deployment Guide

7 min read

Deploy your custom agents and make them accessible to Mindra Platform.

Deployment Options

Option 1: Docker (Recommended)

Package your agent as a Docker container for consistent deployment.

Step 1: Create Dockerfile

TypeScript Agent:

FROM node:20-alpine

WORKDIR /app

COPY package.json pnpm-lock.yaml ./
RUN npm install -g pnpm && pnpm install --frozen-lockfile

COPY . .
RUN pnpm build

EXPOSE 8003

CMD ["node", "dist/index.js"]

Python Agent:

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["python", "agent.py"]

Go Agent:

FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN go build -o agent main.go

FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/agent .

EXPOSE 8002

CMD ["./agent"]

Step 2: Build Image

docker build -t my-agent:latest .

Step 3: Test Locally

docker run -p 8003:8003 \
  -e ANTHROPIC_API_KEY=your_key \
  my-agent:latest

# Test
curl http://localhost:8003/health

Step 4: Push to Registry

# Docker Hub
docker tag my-agent:latest username/my-agent:latest
docker push username/my-agent:latest

# AWS ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789.dkr.ecr.us-east-1.amazonaws.com
docker tag my-agent:latest 123456789.dkr.ecr.us-east-1.amazonaws.com/my-agent:latest
docker push 123456789.dkr.ecr.us-east-1.amazonaws.com/my-agent:latest

# Google Container Registry
docker tag my-agent:latest gcr.io/my-project/my-agent:latest
docker push gcr.io/my-project/my-agent:latest

Option 2: Kubernetes

Deploy to Kubernetes for production-grade orchestration.

Deployment YAML

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-agent
  labels:
    app: my-agent
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-agent
  template:
    metadata:
      labels:
        app: my-agent
    spec:
      containers:
      - name: my-agent
        image: username/my-agent:latest
        ports:
        - containerPort: 8003
        env:
        - name: PORT
          value: "8003"
        - name: ANTHROPIC_API_KEY
          valueFrom:
            secretKeyRef:
              name: agent-secrets
              key: anthropic-api-key
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8003
          initialDelaySeconds: 10
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /health
            port: 8003
          initialDelaySeconds: 5
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: my-agent
spec:
  selector:
    app: my-agent
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8003
  type: LoadBalancer
---
apiVersion: v1
kind: Secret
metadata:
  name: agent-secrets
type: Opaque
stringData:
  anthropic-api-key: "your_key_here"

Deploy

kubectl apply -f deployment.yaml

# Check status
kubectl get pods
kubectl get services

# Get public URL
kubectl get service my-agent

Option 3: Cloud Platforms

AWS (ECS/Fargate)

# Create ECS cluster
aws ecs create-cluster --cluster-name my-agents

# Create task definition
cat > task-definition.json <<EOF
{
  "family": "my-agent",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "containerDefinitions": [
    {
      "name": "my-agent",
      "image": "123456789.dkr.ecr.us-east-1.amazonaws.com/my-agent:latest",
      "portMappings": [
        {
          "containerPort": 8003,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "PORT",
          "value": "8003"
        }
      ],
      "secrets": [
        {
          "name": "ANTHROPIC_API_KEY",
          "valueFrom": "arn:aws:secretsmanager:us-east-1:123456789:secret:agent-keys"
        }
      ]
    }
  ]
}
EOF

aws ecs register-task-definition --cli-input-json file://task-definition.json

# Create service
aws ecs create-service \
  --cluster my-agents \
  --service-name my-agent \
  --task-definition my-agent \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-xxx],securityGroups=[sg-xxx],assignPublicIp=ENABLED}"

Google Cloud Run

# Deploy
gcloud run deploy my-agent \
  --image gcr.io/my-project/my-agent:latest \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated \
  --port 8003 \
  --set-env-vars PORT=8003 \
  --set-secrets ANTHROPIC_API_KEY=agent-keys:latest

# Get URL
gcloud run services describe my-agent --region us-central1 --format 'value(status.url)'

Azure Container Apps

# Create container app environment
az containerapp env create \
  --name my-agent-env \
  --resource-group my-rg \
  --location eastus

# Deploy container
az containerapp create \
  --name my-agent \
  --resource-group my-rg \
  --environment my-agent-env \
  --image username/my-agent:latest \
  --target-port 8003 \
  --ingress external \
  --min-replicas 1 \
  --max-replicas 5 \
  --secrets anthropic-key=your_key \
  --env-vars PORT=8003 ANTHROPIC_API_KEY=secretref:anthropic-key

# Get URL
az containerapp show \
  --name my-agent \
  --resource-group my-rg \
  --query properties.configuration.ingress.fqdn

Option 4: Self-Hosted

Run on your own infrastructure.

Using Docker Compose

# docker-compose.yml
version: '3.8'

services:
  my-agent:
    image: username/my-agent:latest
    ports:
      - "8003:8003"
    environment:
      - PORT=8003
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8003/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
docker-compose up -d

Using systemd

# Create service file
sudo tee /etc/systemd/system/my-agent.service > /dev/null <<EOF
[Unit]
Description=My Custom Agent
After=network.target

[Service]
Type=simple
User=agent
WorkingDirectory=/opt/my-agent
Environment="PORT=8003"
Environment="ANTHROPIC_API_KEY=your_key"
ExecStart=/usr/local/bin/node /opt/my-agent/dist/index.js
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

# Enable and start
sudo systemctl enable my-agent
sudo systemctl start my-agent

# Check status
sudo systemctl status my-agent

Production Checklist

Security

  • Use HTTPS (TLS/SSL certificates)
  • Store secrets securely (environment variables, secret managers)
  • Implement rate limiting
  • Add request authentication (API keys, JWT)
  • Enable CORS only for necessary origins
  • Keep dependencies updated
  • Run security scans (npm audit, Snyk)

Performance

  • Enable horizontal scaling (multiple instances)
  • Implement health checks
  • Configure resource limits (CPU, memory)
  • Add caching where appropriate
  • Optimize Docker image size
  • Use connection pooling for databases
  • Implement request queuing for high load

Monitoring

  • Add logging (structured JSON logs)
  • Export metrics (Prometheus format)
  • Configure alerts (downtime, errors, high latency)
  • Set up APM (Application Performance Monitoring)
  • Track error rates and response times
  • Monitor resource usage

Reliability

  • Implement graceful shutdown
  • Add timeout handling
  • Configure automatic restarts
  • Set up backup instances
  • Implement circuit breakers
  • Add retry logic with exponential backoff
  • Test disaster recovery

Exposing Your Agent

Your agent must be publicly accessible via HTTPS for Mindra Platform to reach it.

Options

1. Public Load Balancer

AWS Application Load Balancer:

aws elbv2 create-load-balancer \
  --name my-agent-lb \
  --subnets subnet-xxx subnet-yyy \
  --security-groups sg-xxx \
  --scheme internet-facing

Google Cloud Load Balancer:

gcloud compute forwarding-rules create my-agent-lb \
  --global \
  --target-http-proxy=my-agent-proxy \
  --ports=443

2. Ingress Controller (Kubernetes)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-agent-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
  - hosts:
    - my-agent.example.com
    secretName: my-agent-tls
  rules:
  - host: my-agent.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-agent
            port:
              number: 80

3. Reverse Proxy (Nginx)

server {
    listen 443 ssl http2;
    server_name my-agent.example.com;

    ssl_certificate /etc/letsencrypt/live/my-agent.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/my-agent.example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8003;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
}

4. Cloudflare Tunnel

# Install cloudflared
# https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/

# Create tunnel
cloudflared tunnel create my-agent

# Configure tunnel
cat > config.yml <<EOF
tunnel: <tunnel-id>
credentials-file: /path/to/<tunnel-id>.json

ingress:
  - hostname: my-agent.example.com
    service: http://localhost:8003
  - service: http_status:404
EOF

# Run tunnel
cloudflared tunnel run my-agent

Environment Variables

Manage configuration through environment variables:

# Required
PORT=8003                          # HTTP port
NODE_ENV=production               # Environment

# Optional - API Keys
ANTHROPIC_API_KEY=sk-xxx          # If using Claude
OPENAI_API_KEY=sk-xxx             # If using OpenAI

# Optional - Database
DATABASE_URL=postgresql://...      # If using database
REDIS_URL=redis://...              # If using Redis

# Optional - Monitoring
PROMETHEUS_PORT=9090               # Metrics port
LOG_LEVEL=info                     # Log level

# Optional - Security
API_KEY_SECRET=xxx                 # For request authentication
CORS_ORIGINS=https://api.mindra.co # CORS allowed origins

Testing Deployment

1. Health Check

curl https://my-agent.example.com/health

Expected:

{
  "status": "healthy",
  "timestamp": 1699632000
}

2. Info Endpoint

curl https://my-agent.example.com/info

Expected:

{
  "id": "my-custom-agent",
  "name": "My Custom Agent",
  "version": "1.0.0"
}

3. Execute Endpoint

curl -X POST https://my-agent.example.com/execute \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "prompt": "test query",
      "context": {}
    },
    "metadata": {
      "requestId": "test",
      "userId": "test",
      "timeout": 30000
    }
  }'

4. Load Test

# Using Apache Bench
ab -n 1000 -c 10 https://my-agent.example.com/health

# Using k6
k6 run load-test.js

Next Steps

Once deployed, register your agent with Mindra Platform:

Registration Guide

Support