This guide covers deployment infrastructure for aixgo applications.
- Overview
- Architecture
- Prerequisites
- Local Development
- Cloud Run Deployment
- Kubernetes Deployment
- CI/CD Pipeline
- Monitoring & Observability
- Security
- Troubleshooting
The deployment infrastructure provides:
- gRPC Implementation: Full MCP over gRPC with TLS support
- Cloud Run: Serverless deployment with auto-scaling
- Kubernetes: Production-grade container orchestration
- CI/CD: Automated build, test, and deployment via GitHub Actions
- Observability: Prometheus metrics, health checks, and distributed tracing
┌────────────────────────────────────────────────────────────────┐
│ Internet / Load Balancer │
└────────────────────────┬───────────────────────────────────────┘
│
┌───────────────┴────────────────┐
│ │
┌────▼─────────┐ ┌──────▼──────────┐
│ Aixgo │ │ MCP Server │
│ Orchestrator │◄────────────►│ (HuggingFace) │
│ │ gRPC │ │
│ - Agents │ │ - Tools │
│ - Routing │ │ - gRPC/HTTP │
│ - Metrics │ │ - Metrics │
└────┬─────────┘ └─────────────────┘
│
│ HTTP
│
┌────▼─────────┐
│ Ollama │
│ Service │
│ │
│ - LLM Models │
│ - Inference │
└──────────────┘
-
Aixgo Orchestrator (
cmd/aixgo/)- Agent coordination and message routing
- HTTP API (port 8080) and gRPC (port 9090)
- Health checks and metrics
-
MCP Server (
cmd/mcp-server/)- Model Context Protocol implementation
- HuggingFace integration
- gRPC and HTTP APIs
-
Ollama Service
- Local LLM runtime
- Model serving (port 11434)
- Persistent storage for models
- Docker: Container runtime
- kubectl: Kubernetes CLI (for K8s deployment)
- gcloud: Google Cloud SDK (for GCP deployment)
- Go 1.23+: For local development
- protoc: Protocol buffer compiler
# Install Go dependencies
go mod download
# Install protoc plugins
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# Generate protobuf code (using Go tool in the future)
go run proto/mcp/generate.go# Start all services
docker-compose up -d
# View logs
docker-compose logs -f
# Stop services
docker-compose downServices will be available at:
- Aixgo: http://localhost:8080
- Ollama: http://localhost:11434
# Terminal 1: Start Ollama
docker run -p 11434:11434 ollama/ollama:latest
# Terminal 2: Start MCP Server
go run cmd/mcp-server/main.go
# Terminal 3: Start Orchestrator
go run cmd/aixgo/main.go -config examples/huggingface-mcp/config.yaml# Health checks
curl http://localhost:8080/health/live
curl http://localhost:8080/health/ready
curl http://localhost:8080/health
# Metrics
curl http://localhost:8080/metrics# Set environment variables
export GCP_PROJECT_ID="your-project-id"
export GCP_REGION="us-central1"
export XAI_API_KEY="<your-xai-api-key>"
export OPENAI_API_KEY="<your-openai-api-key>"
export HUGGINGFACE_API_KEY="<your-huggingface-api-key>"
# Deploy using gcloud
gcloud run deploy aixgo-mcp \
--image us-central1-docker.pkg.dev/$GCP_PROJECT_ID/aixgo/mcp-server:latest \
--region $GCP_REGION \
--platform managed \
--allow-unauthenticatedThe deployment process:
- Enable required GCP APIs
- Create Artifact Registry repository
- Build and push Docker images
- Create service account with permissions
- Store secrets in Secret Manager
- Deploy to Cloud Run
- Run health checks
See deploy/cloudrun/README.md for detailed instructions.
# Configure Docker for Artifact Registry
gcloud auth configure-docker us-central1-docker.pkg.dev
# Build image
docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/aixgo/mcp-server:latest \
-f docker/aixgo.Dockerfile .
# Push image
docker push us-central1-docker.pkg.dev/${PROJECT_ID}/aixgo/mcp-server:latest# Store API keys in Secret Manager
echo -n "${XAI_API_KEY}" | gcloud secrets create xai-api-key --data-file=-
echo -n "${OPENAI_API_KEY}" | gcloud secrets create openai-api-key --data-file=-
echo -n "${HUGGINGFACE_API_KEY}" | gcloud secrets create huggingface-api-key --data-file=-Security Warning: The --allow-unauthenticated flag grants public access to your service and should only be used for local/development/test deployments. For production
deployments, remove this flag or use --no-allow-unauthenticated and configure IAM authentication.
gcloud run deploy aixgo-mcp \
--image=us-central1-docker.pkg.dev/${PROJECT_ID}/aixgo/mcp-server:latest \
--platform=managed \
--region=us-central1 \
--allow-unauthenticated \
--min-instances=0 \
--max-instances=100 \
--cpu=2 \
--memory=2Gi \
--timeout=300 \
--set-secrets="XAI_API_KEY=xai-api-key:latest,OPENAI_API_KEY=openai-api-key:latest,HUGGINGFACE_API_KEY=huggingface-api-key:latest"For production deployments, use authenticated access instead:
# Deploy with authentication required
gcloud run deploy aixgo-mcp \
--image=us-central1-docker.pkg.dev/${PROJECT_ID}/aixgo/mcp-server:latest \
--no-allow-unauthenticated \
--platform=managed \
--region=us-central1 \
--min-instances=0 \
--max-instances=100 \
--cpu=2 \
--memory=2Gi \
--timeout=300 \
--set-secrets="XAI_API_KEY=xai-api-key:latest,OPENAI_API_KEY=openai-api-key:latest,HUGGINGFACE_API_KEY=huggingface-api-key:latest"
# Grant access to specific service account or user
gcloud run services add-iam-policy-binding aixgo-mcp \
--region=us-central1 \
--member="serviceAccount:caller@${PROJECT_ID}.iam.gserviceaccount.com" \
--role="roles/run.invoker"See the Authentication section (line 522) for comprehensive authentication configuration, IAM setup, and service account management.
See deploy/cloudrun/service.yaml for full configuration including:
- Resource limits (CPU, memory)
- Scaling configuration
- Health checks
- Environment variables
- Secret mounting
gcloud container clusters create aixgo-cluster \
--region=us-central1 \
--num-nodes=3 \
--machine-type=n1-standard-4 \
--enable-autoscaling \
--min-nodes=3 \
--max-nodes=10 \
--enable-stackdriver-kubernetes \
--enable-ip-aliasgcloud container clusters get-credentials aixgo-cluster --region=us-central1# Set environment variables
export GCP_PROJECT_ID="your-project-id"
export GKE_CLUSTER="aixgo-cluster"
export GKE_ZONE="us-central1-a"
export XAI_API_KEY="<your-xai-api-key>"
export OPENAI_API_KEY="<your-openai-api-key>"
export HUGGINGFACE_API_KEY="<your-huggingface-api-key>"
# Get cluster credentials
gcloud container clusters get-credentials $GKE_CLUSTER --zone $GKE_ZONE
# Deploy using kubectl
kubectl apply -k deploy/k8s/overlays/staging# Get cluster credentials
gcloud container clusters get-credentials $GKE_CLUSTER --zone $GKE_ZONE
# Deploy using kubectl
kubectl apply -k deploy/k8s/overlays/productionThe deployment process:
- Authenticate to GCP and get cluster credentials
- Build and push Docker images
- Create namespace and secrets
- Apply Kubernetes manifests via kustomize
- Wait for rollout completion
See deploy/k8s/README.md for detailed instructions.
The deployment includes:
- Deployments: Aixgo orchestrator, MCP server, Ollama
- Services: ClusterIP services for internal communication
- HPA: Horizontal Pod Autoscaling based on CPU/memory
- Ingress: External access with TLS termination
- ConfigMaps: Configuration management
- Secrets: API keys and certificates
- RBAC: Service accounts and permissions
- PVC: Persistent storage for Ollama models
Triggered on push and pull requests:
- Lint (golangci-lint)
- Test (unit tests, race detection, coverage)
- Build (multi-platform binaries)
- Docker build (without push)
- Security scan (Trivy, Gosec)Triggered on version tags (v*.*.*):
- Build multi-platform binaries
- Build and push Docker images (amd64, arm64)
- Create GitHub release with artifacts
- Push to GitHub Container Registry and Docker HubTriggered on main branch changes:
- Authenticate to GCP
- Build and push Docker image
- Deploy to Cloud Run
- Run health checks
- Create deployment summaryTriggered on main branch changes:
- Authenticate to GCP
- Build and push Docker images
- Update Kubernetes manifests
- Deploy with kustomize
- Run smoke tests
- Send notificationsConfigure in repository settings → Secrets and variables → Actions:
GCP_PROJECT_ID: Your GCP project ID
WIF_PROVIDER: Workload Identity Federation provider
WIF_SERVICE_ACCOUNT: Service account for WIF
CLOUD_RUN_SA: Cloud Run service account
XAI_API_KEY: xAI API key (optional)
OPENAI_API_KEY: OpenAI API key (optional)
HUGGINGFACE_API_KEY: HuggingFace API key (optional)
SLACK_WEBHOOK_URL: Slack webhook for notifications (optional)# Tag a new version
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
# GitHub Actions will automatically:
# 1. Build binaries for all platforms
# 2. Build and push Docker images
# 3. Create GitHub release with artifactsAll services expose three health check endpoints:
# Liveness: Is the process running?
curl http://service:8080/health/live
# Readiness: Can it accept traffic?
curl http://service:8080/health/ready
# Detailed health status
curl http://service:8080/healthResponse format:
{
"status": "healthy",
"timestamp": "2025-11-20T12:00:00Z",
"version": "1.0.0",
"uptime": "1h30m",
"checks": {
"ping": {
"status": "healthy",
"message": "OK",
"last_checked": "2025-11-20T12:00:00Z"
}
},
"system": {
"num_goroutines": 42,
"num_cpu": 4,
"mem_alloc_mb": 128,
"mem_sys_mb": 256
}
}Metrics endpoint: http://service:8080/metrics
HTTP Metrics:
aixgo_http_requests_total{method="GET",path="/health",status="200"}
aixgo_http_request_duration_seconds{method="GET",path="/health"}
MCP Metrics:
aixgo_mcp_tool_calls_total{tool="echo",status="success"}
aixgo_mcp_tool_call_duration_seconds{tool="echo"}
gRPC Metrics:
aixgo_grpc_requests_total{method="/mcp.MCPService/CallTool",status="OK"}
aixgo_grpc_request_duration_seconds{method="/mcp.MCPService/CallTool"}
Agent Metrics:
aixgo_agent_messages_total{agent="analyzer",type="request"}
aixgo_agent_execution_duration_seconds{agent="analyzer"}
System Metrics:
aixgo_active_connections
aixgo_memory_usage_bytes
aixgo_goroutines
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: aixgo
namespace: aixgo
spec:
selector:
matchLabels:
app: aixgo
endpoints:
- port: http
path: /metrics
interval: 30sUse Cloud Monitoring integration or deploy a Prometheus instance that scrapes the metrics endpoint.
OpenTelemetry is integrated by default:
// Traces are automatically created for:
// - HTTP requests
// - gRPC calls
// - Agent executions
// - MCP tool callsConfigure trace exporter via environment variables:
OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318
OTEL_SERVICE_NAME=aixgo-orchestrator
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1Enable authentication:
gcloud run services update aixgo-mcp --no-allow-unauthenticatedAccess with service account:
TOKEN=$(gcloud auth print-identity-token)
curl -H "Authorization: Bearer ${TOKEN}" https://service-url/healthUse Ingress with authentication:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/auth-type: basic
nginx.ingress.kubernetes.io/auth-secret: basic-authAutomatic TLS termination. For custom domains:
gcloud run domain-mappings create \
--service=aixgo-mcp \
--domain=api.example.comUse cert-manager for automatic certificates:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.3/cert-manager.yamlUse .env file (never commit):
cp .env.example .env
# Edit .env with your keysGCP Secret Manager:
# Create secret
gcloud secrets create api-key --data-file=-
# Grant access
gcloud secrets add-iam-policy-binding api-key \
--member="serviceAccount:service@project.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"Kubernetes Secrets:
kubectl create secret generic api-keys \
--from-literal=key=value \
-n aixgo- Use VPC connector for private resources
- Configure ingress settings (internal, internal-and-cloud-load-balancing, all)
Apply network policies:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: aixgo-netpol
spec:
podSelector:
matchLabels:
app: aixgo
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: ingress-nginx
egress:
- to:
- podSelector:
matchLabels:
app: ollamaCheck logs:
# Cloud Run
gcloud run services logs read aixgo-mcp --limit=50
# Kubernetes
kubectl logs -l app=aixgo -n aixgo --tail=50Common issues:
- Missing environment variables
- Invalid API keys
- Insufficient resources
- Image pull errors
Diagnose:
# Check metrics
curl http://service:8080/metrics | grep duration
# Check resource usage
kubectl top pods -n aixgoSolutions:
- Scale up resources
- Increase replica count
- Optimize Ollama model loading
- Enable request caching
Test connectivity:
# Port forward for testing
kubectl port-forward svc/aixgo-service 8080:8080 -n aixgo
# Test from within cluster
kubectl run test --rm -it --image=curlimages/curl -- sh
curl http://aixgo-service:8080/healthCheck:
- Service endpoints:
kubectl get endpoints -n aixgo - Network policies
- Firewall rules
- DNS resolution
Monitor memory:
# Check memory usage
curl http://service:8080/metrics | grep memory
# Kubernetes
kubectl top pods -n aixgoSolutions:
- Increase memory limits
- Use smaller Ollama models
- Enable memory profiling
- Check for memory leaks
Common issues:
- Connection refused: Check gRPC port (9090) is exposed
- TLS errors: Verify certificate configuration
- Deadline exceeded: Increase timeout values
- Unavailable: Check service health and connectivity
Debug:
# Test gRPC endpoint with grpcurl
grpcurl -plaintext localhost:9090 list
grpcurl -plaintext localhost:9090 mcp.MCPService/Ping- Cloud Run Documentation
- GKE Documentation
- Prometheus Documentation
- gRPC Documentation
- GitHub Actions Documentation
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: docs/