Deployment - Guía Completa
Esta guía proporciona instrucciones detalladas para el despliegue del sistema IRIS en diferentes entornos: desarrollo, staging y producción.
🎯 Visión General del Deployment
Arquitectura de Deployment
Ambientes Soportados
Desarrollo Local
- Docker Compose: Orquestación simple de contenedores
- Hot Reload: Recarga automática de código
- Debug Mode: Logs detallados y herramientas de debug
- Recursos: Mínimos para desarrollo local
Staging
- Docker Swarm: Cluster de contenedores
- Load Balancing: Distribución de carga básica
- Monitoring: Métricas y logs centralizados
- Testing: Ambiente para testing de integración
Producción
- Kubernetes: Orquestación avanzada y escalamiento
- High Availability: Redundancia y failover automático
- Auto Scaling: Escalamiento automático basado en métricas
- Security: Configuración de seguridad enterprise
🚀 Deployment Local (Desarrollo)
Prerrequisitos
# Verificar instalaciones requeridas
docker --version # >= 20.10
docker-compose --version # >= 2.0
git --version # >= 2.30
python --version # >= 3.9
node --version # >= 16.0
Setup Inicial
# 1. Clonar repositorio
git clone https://github.com/your-org/iris-ocr.git
cd iris-ocr
# 2. Configurar variables de entorno
cp .env.example .env
# Editar .env con configuraciones locales
# 3. Construir imágenes base
docker-compose build
# 4. Inicializar datos de desarrollo
docker-compose run --rm init-data
# 5. Levantar servicios
docker-compose up -d
Configuración de Entorno (.env)
# Ambiente
ENVIRONMENT=development
DEBUG=true
# Base de datos
DATABASE_URL=postgresql://iris:password@postgres:5432/iris_dev
REDIS_URL=redis://redis:6379/0
# API Configuration
API_HOST=0.0.0.0
API_PORT=8000
API_WORKERS=1
# ML Models
MODEL_CACHE_DIR=/app/data/models
PADDLE_MODELS_DIR=/root/.paddlex
# Monitoring
PROMETHEUS_ENABLED=true
GRAFANA_ENABLED=true
# Security (Development only)
SECRET_KEY=dev-secret-key-change-in-production
JWT_SECRET=dev-jwt-secret-change-in-production
Docker Compose Configuration
version: '3.8'
services:
# API Gateway
api-gateway:
build:
context: ./packages/api-gateway
target: development
ports:
- "8000:8000"
environment:
- DEBUG=true
volumes:
- ./packages/api-gateway:/app
- ./data:/app/data
depends_on:
- postgres
- redis
command: uvicorn app:app --host 0.0.0.0 --port 8000 --reload
# Image Processor Service
image-processor:
build:
context: ./packages/image-processor
target: development
ports:
- "8001:8001"
volumes:
- ./packages/image-processor:/app
- ./data:/app/data
command: uvicorn app:app --host 0.0.0.0 --port 8001 --reload
# ML Services
ml-embeddings:
build:
context: ./packages/ml-embeddings
target: development
ports:
- "8002:8002"
volumes:
- ./packages/ml-embeddings:/app
- ./data:/app/data
deploy:
resources:
reservations:
devices:
- capabilities: [gpu] # Si GPU disponible
ml-classifier:
build:
context: ./packages/ml-classifier
target: development
ports:
- "8003:8003"
volumes:
- ./packages/ml-classifier:/app
- ./data:/app/data
# OCR Service
ocr-extractor:
build:
context: ./packages/ocr-extractor
target: development
ports:
- "8004:8004"
volumes:
- ./packages/ocr-extractor:/app
- ./data:/app/data
- paddle_models:/root/.paddlex
# Frontend (React)
frontend:
build:
context: ./packages/frontend
target: development
ports:
- "3000:3000"
volumes:
- ./packages/frontend:/app
- /app/node_modules
environment:
- REACT_APP_API_URL=http://localhost:8000
command: npm start
# Database
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: iris_dev
POSTGRES_USER: iris
POSTGRES_PASSWORD: password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/sql/init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
# Cache
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
# Monitoring
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3001:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
volumes:
postgres_data:
redis_data:
grafana_data:
paddle_models:
Comandos de Desarrollo
# Iniciar servicios
docker-compose up -d
# Ver logs en tiempo real
docker-compose logs -f api-gateway
# Reiniciar servicio específico
docker-compose restart ml-classifier
# Ejecutar comandos en contenedor
docker-compose exec api-gateway bash
# Parar servicios
docker-compose down
# Limpiar todo (¡Cuidado!)
docker-compose down -v --remove-orphans
🏗️ Deployment Staging
Configuración Docker Swarm
# 1. Inicializar swarm
docker swarm init
# 2. Configurar registry privado (opcional)
docker service create --name registry \
--publish 5000:5000 \
registry:2
# 3. Construir y pushear imágenes
docker-compose -f docker-compose.prod.yml build
docker-compose -f docker-compose.prod.yml push
# 4. Deploy en swarm
docker stack deploy -c stack.yml iris-staging
Stack Configuration (stack.yml)
version: '3.8'
services:
api-gateway:
image: iris/api-gateway:staging
ports:
- "8000:8000"
environment:
- ENVIRONMENT=staging
- DATABASE_URL=postgresql://iris:${DB_PASSWORD}@postgres:5432/iris_staging
deploy:
replicas: 2
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
placement:
constraints:
- node.role == worker
networks:
- iris-network
# Load Balancer
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/staging.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/ssl/certs
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
networks:
- iris-network
networks:
iris-network:
driver: overlay
configs:
nginx_config:
file: ./nginx/staging.conf
secrets:
db_password:
external: true
Nginx Configuration (staging)
upstream api_gateway {
server api-gateway:8000;
}
upstream frontend {
server frontend:3000;
}
server {
listen 80;
server_name staging.iris-ocr.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name staging.iris-ocr.com;
ssl_certificate /etc/ssl/certs/staging.crt;
ssl_certificate_key /etc/ssl/certs/staging.key;
# API routes
location /api/ {
proxy_pass http://api_gateway;
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;
# Timeouts for long processing
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
# Frontend routes
location / {
proxy_pass http://frontend;
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;
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
☸️ Deployment Producción (Kubernetes)
Cluster Setup
# 1. Configurar kubectl
kubectl config current-context
# 2. Crear namespace
kubectl create namespace iris-production
# 3. Configurar secrets
kubectl create secret generic iris-secrets \
--from-literal=database-url="${DATABASE_URL}" \
--from-literal=jwt-secret="${JWT_SECRET}" \
-n iris-production
# 4. Aplicar configuraciones
kubectl apply -f k8s/ -n iris-production
Kubernetes Manifests
API Gateway Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-gateway
namespace: iris-production
spec:
replicas: 3
selector:
matchLabels:
app: api-gateway
template:
metadata:
labels:
app: api-gateway
spec:
containers:
- name: api-gateway
image: iris/api-gateway:v1.0.0
ports:
- containerPort: 8000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: iris-secrets
key: database-url
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: iris-secrets
key: jwt-secret
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: api-gateway-service
namespace: iris-production
spec:
selector:
app: api-gateway
ports:
- port: 8000
targetPort: 8000
type: ClusterIP
Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-gateway-hpa
namespace: iris-production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-gateway
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Ingress Configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: iris-ingress
namespace: iris-production
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
spec:
tls:
- hosts:
- api.iris-ocr.com
- app.iris-ocr.com
secretName: iris-tls
rules:
- host: api.iris-ocr.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-gateway-service
port:
number: 8000
- host: app.iris-ocr.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 3000
🔧 Scripts de Automatización
Deploy Script
#!/bin/bash
# deploy.sh - Script de deployment automatizado
set -e
ENVIRONMENT=${1:-staging}
VERSION=${2:-latest}
echo "🚀 Iniciando deployment a $ENVIRONMENT..."
case $ENVIRONMENT in
"development")
echo "📦 Construyendo servicios..."
docker-compose build
echo "🔄 Reiniciando servicios..."
docker-compose down
docker-compose up -d
;;
"staging")
echo "🏗️ Construyendo para staging..."
docker-compose -f docker-compose.prod.yml build
echo "📤 Pusheando imágenes..."
docker-compose -f docker-compose.prod.yml push
echo "🚀 Desplegando en swarm..."
docker stack deploy -c stack.yml iris-staging
;;
"production")
echo "☸️ Desplegando en Kubernetes..."
# Actualizar imágenes
kubectl set image deployment/api-gateway \
api-gateway=iris/api-gateway:$VERSION \
-n iris-production
kubectl set image deployment/ml-classifier \
ml-classifier=iris/ml-classifier:$VERSION \
-n iris-production
# Esperar rollout
kubectl rollout status deployment/api-gateway -n iris-production
kubectl rollout status deployment/ml-classifier -n iris-production
;;
*)
echo "❌ Ambiente no válido: $ENVIRONMENT"
echo "Uso: $0 [development|staging|production] [version]"
exit 1
;;
esac
echo "✅ Deployment completado exitosamente"
# Verificar health checks
echo "🔍 Verificando servicios..."
sleep 10
case $ENVIRONMENT in
"development")
curl -f http://localhost:8000/health || echo "⚠️ API Gateway no responde"
;;
"staging")
curl -f https://staging.iris-ocr.com/health || echo "⚠️ Staging no responde"
;;
"production")
curl -f https://api.iris-ocr.com/health || echo "⚠️ Producción no responde"
;;
esac
Rollback Script
#!/bin/bash
# rollback.sh - Script de rollback
set -e
ENVIRONMENT=${1:-production}
REVISION=${2:-previous}
echo "🔙 Iniciando rollback en $ENVIRONMENT a revisión $REVISION..."
case $ENVIRONMENT in
"staging")
# Docker Swarm rollback
docker service rollback iris-staging_api-gateway
docker service rollback iris-staging_ml-classifier
;;
"production")
# Kubernetes rollback
kubectl rollout undo deployment/api-gateway -n iris-production
kubectl rollout undo deployment/ml-classifier -n iris-production
# Esperar completar rollback
kubectl rollout status deployment/api-gateway -n iris-production
kubectl rollout status deployment/ml-classifier -n iris-production
;;
*)
echo "❌ Ambiente no válido para rollback: $ENVIRONMENT"
exit 1
;;
esac
echo "✅ Rollback completado"
📊 Monitoreo Post-Deployment
Health Checks
# Script de verificación post-deployment
./scripts/health-check.sh production
# Verifica:
# - Servicios corriendo
# - Endpoints respondiendo
# - Base de datos conectada
# - Cache funcionando
# - Métricas disponibles
Smoke Tests
# Tests básicos post-deployment
./scripts/smoke-tests.sh production
# Incluye:
# - Upload de imagen test
# - Procesamiento end-to-end
# - Descarga de resultados
# - Métricas de performance
🚨 Troubleshooting Deployment
Problemas Comunes
Servicios No Inician
# Verificar logs
docker-compose logs service-name
kubectl logs deployment/service-name -n iris-production
# Verificar recursos
docker stats
kubectl top pods -n iris-production
# Verificar configuración
docker-compose config
kubectl describe deployment service-name -n iris-production
Problemas de Conectividad
# Verificar red
docker network ls
kubectl get services -n iris-production
# Test de conectividad
docker-compose exec api-gateway curl ml-classifier:8003/health
kubectl exec -it deployment/api-gateway -- curl ml-classifier:8003/health
Performance Issues
# Verificar métricas
curl http://localhost:9090/metrics # Prometheus
kubectl port-forward svc/prometheus 9090:9090
# Scaling manual
docker service scale iris-staging_api-gateway=5
kubectl scale deployment api-gateway --replicas=5 -n iris-production
📚 Próximos Pasos
- Monitoreo: Configurar alertas y dashboards
- Backup: Estrategia de respaldos
- Security: Hardening de seguridad
- Performance: Optimización del sistema
¿Problemas con el deployment? Consulta la guía de troubleshooting o contacta al equipo de DevOps.