# Despliegue y Arquitectura Docker {#sec-deployment}

## Arquitectura General

BrechaSnipApp utiliza una arquitectura basada en contenedores Docker para garantizar la consistencia entre los entornos de desarrollo y producción. El sistema se compone de dos servicios principales orquestados mediante Docker Compose:

1.  **Frontend (`web`)**: Aplicación Next.js que sirve la interfaz de usuario.
2.  **Backend (`api`)**: Servicio R con Plumber que procesa los cálculos y gestiona los datos.

Esta arquitectura desacoplada permite escalar cada componente de manera independiente y simplifica el despliegue en cualquier servidor que soporte Docker.

## Docker Compose (Recomendado)

### Estructura

```
BrechaSnipApp/
├── docker-compose.yml
├── api/
│   ├── Dockerfile
│   ├── plumber.R
│   └── entrypoint.R
└── web/
    └── Dockerfile
```

### docker-compose.yml

```yaml
version: '3.8'

services:
  api:
    build: ./api
    ports:
      - "8000:8000"
    volumes:
      - ./brechaspnip:/app/brechaspnip
      - ./geodomR:/app/geodomR
    environment:
      - R_VERSION=4.4.0
  
  web:
    build: ./web
    ports:
      - "3000:3000"
    depends_on:
      - api
    environment:
      - NEXT_PUBLIC_API_URL=http://api:8000
```

### Comandos

```bash
# Construir imágenes
docker-compose build

# Iniciar servicios
docker-compose up -d

# Ver logs
docker-compose logs -f

# Detener servicios
docker-compose down
```

## Dockerfile API

```dockerfile
FROM rocker/r-ver:4.4.0

# Dependencias del sistema
RUN apt-get update && apt-get install -y \
    libudunits2-dev \
    libgdal-dev \
    libproj-dev \
    libssl-dev \
    && rm -rf /var/lib/apt/lists/*

# Instalar plumber2
RUN R -e "install.packages('plumber2', repos='https://cloud.r-project.org/')"

# Directorio de trabajo
WORKDIR /app

# Copiar paquetes locales
COPY brechaspnip /app/brechaspnip
COPY geodomR /app/geodomR

# Instalar paquetes
RUN R -e "install.packages('remotes')"
RUN R -e "remotes::install_local('/app/geodomR', dependencies = TRUE)"
RUN R -e "remotes::install_local('/app/brechaspnip', dependencies = TRUE)"

# Copiar archivos API
COPY api/plumber.R /app/plumber.R
COPY api/entrypoint.R /app/entrypoint.R

# Exponer puerto
EXPOSE 8000

# Comando de inicio
CMD ["Rscript", "/app/entrypoint.R"]
```

## entrypoint.R

```r
library(plumber2)

# Cargar API
pr <- plumb("plumber.R")

# Configurar opciones
options(
  plumber.port = 8000,
  plumber.host = "0.0.0.0"
)

# Iniciar servidor
pr$run()
```

## Despliegue en Producción

### Requisitos

- Docker y Docker Compose
- 4GB RAM mínimo (8GB recomendado)
- CPU multi-core (los cálculos son intensivos)

### Variables de Entorno

```bash
# .env
R_VERSION=4.4.0
API_PORT=8000
WEB_PORT=3000
API_WORKERS=4  # Número de workers R
```

### Configuración de Recursos

En `docker-compose.yml`:

```yaml
services:
  api:
    deploy:
      resources:
        limits:
          cpus: '4.0'
          memory: 8G
        reservations:
          cpus: '2.0'
          memory: 4G
```

### Nginx Reverse Proxy

```nginx
upstream api_backend {
    server localhost:8000;
}

server {
    listen 80;
    server_name api.brechasnip.example.com;

    location / {
        proxy_pass http://api_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_read_timeout 300s;  # Timeouts largos para cálculos
    }
}
```

### Monitoreo

```bash
# Ver uso de recursos
docker stats

# Ver logs en tiempo real
docker-compose logs -f api

# Reiniciar si hay problemas
docker-compose restart api
```

## Troubleshooting

### API no responde

```bash
# Verificar que el contenedor está corriendo
docker ps

# Ver logs de errores
docker-compose logs api

# Reiniciar servicio
docker-compose restart api
```

### Cálculos muy lentos

- Aumentar workers R
- Aumentar recursos de CPU/RAM
- Considerar cache de resultados

### Errores de memoria

- Aumentar límite de memoria en docker-compose
- Reducir workers concurrentes
- Procesar indicadores en lotes

## Actualización

```bash
# Detener servicios
docker-compose down

# Actualizar código
git pull

# Reconstruir imágenes
docker-compose build --no-cache

# Reiniciar
docker-compose up -d
```
