Skip to main content

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


¿Problemas con el deployment? Consulta la guía de troubleshooting o contacta al equipo de DevOps.