initial commit
This commit is contained in:
213
docker/README.md
Normal file
213
docker/README.md
Normal file
@@ -0,0 +1,213 @@
|
||||
# 🐳 Docker para Balotario Licencia A-I
|
||||
|
||||
Este directorio contiene la configuración de Docker para la aplicación Balotario.
|
||||
|
||||
## 📁 Archivos de Docker
|
||||
|
||||
### `Dockerfile`
|
||||
**Imagen principal de la aplicación**
|
||||
|
||||
#### Características:
|
||||
- ✅ **Base**: Python 3.11-slim (imagen ligera)
|
||||
- ✅ **Usuario no-root** para seguridad
|
||||
- ✅ **Multi-stage** optimizado para producción
|
||||
- ✅ **Health check** integrado
|
||||
- ✅ **Variables de entorno** configurables
|
||||
|
||||
### `docker-compose.yml`
|
||||
**Orquestación de servicios**
|
||||
|
||||
#### Servicios incluidos:
|
||||
- **balotario**: Aplicación Flask principal
|
||||
- **nginx**: Proxy reverso (opcional)
|
||||
|
||||
### `nginx.conf`
|
||||
**Configuración de Nginx**
|
||||
|
||||
#### Funcionalidades:
|
||||
- ✅ **Proxy reverso** hacia Flask
|
||||
- ✅ **Compresión gzip** para mejor rendimiento
|
||||
- ✅ **Rate limiting** para protección
|
||||
- ✅ **Headers de seguridad**
|
||||
- ✅ **Cache de archivos estáticos**
|
||||
|
||||
## 🚀 Uso Rápido
|
||||
|
||||
### Opción 1: Docker Simple
|
||||
```bash
|
||||
# Construir imagen
|
||||
docker build -t balotario .
|
||||
|
||||
# Ejecutar en desarrollo
|
||||
docker run -p 5000:5000 -e FLASK_ENV=development balotario
|
||||
|
||||
# Ejecutar en producción
|
||||
docker run -d -p 5000:5000 -e FLASK_ENV=production balotario
|
||||
```
|
||||
|
||||
### Opción 2: Docker Compose (Recomendado)
|
||||
```bash
|
||||
# Iniciar todos los servicios
|
||||
docker-compose up -d
|
||||
|
||||
# Ver logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Detener servicios
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### Opción 3: Script de Utilidades
|
||||
```bash
|
||||
# Usar el script helper
|
||||
./scripts/docker.sh build
|
||||
./scripts/docker.sh compose-up
|
||||
./scripts/docker.sh logs
|
||||
./scripts/docker.sh clean
|
||||
```
|
||||
|
||||
## 🔧 Configuración
|
||||
|
||||
### Variables de Entorno
|
||||
|
||||
#### Para Desarrollo:
|
||||
```bash
|
||||
FLASK_ENV=development
|
||||
FLASK_DEBUG=true
|
||||
DOCKER_CONTAINER=true
|
||||
```
|
||||
|
||||
#### Para Producción:
|
||||
```bash
|
||||
FLASK_ENV=production
|
||||
FLASK_DEBUG=false
|
||||
DOCKER_CONTAINER=true
|
||||
SECRET_KEY=tu_clave_secreta_aqui
|
||||
```
|
||||
|
||||
### Puertos
|
||||
- **5000**: Aplicación Flask
|
||||
- **80**: Nginx (si se usa)
|
||||
- **443**: HTTPS (si se configura)
|
||||
|
||||
## 📊 Recursos
|
||||
|
||||
### Imagen Docker
|
||||
- **Tamaño base**: ~150MB (Python slim)
|
||||
- **Tamaño final**: ~200MB (con dependencias)
|
||||
- **RAM recomendada**: 512MB mínimo
|
||||
- **CPU**: 1 core suficiente
|
||||
|
||||
### Volúmenes
|
||||
```yaml
|
||||
volumes:
|
||||
- ./data:/app/data:ro # Datos de solo lectura
|
||||
- balotario-logs:/app/logs # Logs persistentes
|
||||
```
|
||||
|
||||
## 🛡️ Seguridad
|
||||
|
||||
### Medidas Implementadas:
|
||||
- ✅ **Usuario no-root** en el contenedor
|
||||
- ✅ **Health checks** para monitoreo
|
||||
- ✅ **Rate limiting** en Nginx
|
||||
- ✅ **Headers de seguridad**
|
||||
- ✅ **Secrets** via variables de entorno
|
||||
|
||||
### Recomendaciones Adicionales:
|
||||
- 🔒 Usar **secrets de Docker** para claves
|
||||
- 🔒 Configurar **HTTPS** con certificados
|
||||
- 🔒 Implementar **logging** centralizado
|
||||
- 🔒 Usar **registry privado** para imágenes
|
||||
|
||||
## 🚀 Despliegue
|
||||
|
||||
### Desarrollo Local
|
||||
```bash
|
||||
# Clonar proyecto
|
||||
git clone <repo>
|
||||
cd balotario-licencia-a1
|
||||
|
||||
# Iniciar con Docker Compose
|
||||
docker-compose up -d
|
||||
|
||||
# Acceder a la aplicación
|
||||
open http://localhost:5000
|
||||
```
|
||||
|
||||
### Producción
|
||||
```bash
|
||||
# Variables de entorno
|
||||
export FLASK_ENV=production
|
||||
export SECRET_KEY=tu_clave_super_secreta
|
||||
|
||||
# Construir y ejecutar
|
||||
docker build -t balotario:prod .
|
||||
docker run -d -p 80:5000 \
|
||||
-e FLASK_ENV=production \
|
||||
-e SECRET_KEY=$SECRET_KEY \
|
||||
--name balotario-prod \
|
||||
--restart unless-stopped \
|
||||
balotario:prod
|
||||
```
|
||||
|
||||
### Con Nginx (Recomendado para Producción)
|
||||
```bash
|
||||
# Usar Docker Compose completo
|
||||
docker-compose -f docker-compose.yml up -d
|
||||
|
||||
# Acceder via Nginx
|
||||
open http://localhost
|
||||
```
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Problemas Comunes
|
||||
|
||||
#### Puerto ocupado:
|
||||
```bash
|
||||
# Cambiar puerto en docker-compose.yml
|
||||
ports:
|
||||
- "8080:5000" # Usar puerto 8080 en lugar de 5000
|
||||
```
|
||||
|
||||
#### Permisos:
|
||||
```bash
|
||||
# Verificar permisos de archivos
|
||||
ls -la data/
|
||||
chmod 644 data/balotario_clase_a_cat_I.md
|
||||
```
|
||||
|
||||
#### Logs:
|
||||
```bash
|
||||
# Ver logs detallados
|
||||
docker-compose logs -f balotario
|
||||
docker logs balotario-prod
|
||||
```
|
||||
|
||||
#### Limpiar todo:
|
||||
```bash
|
||||
# Limpiar completamente
|
||||
./scripts/docker.sh clean
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
## 📈 Monitoreo
|
||||
|
||||
### Health Checks
|
||||
```bash
|
||||
# Verificar salud del contenedor
|
||||
docker inspect balotario-prod | grep Health -A 10
|
||||
|
||||
# Endpoint de salud
|
||||
curl http://localhost:5000/
|
||||
```
|
||||
|
||||
### Métricas
|
||||
- **CPU**: `docker stats balotario-prod`
|
||||
- **Memoria**: `docker stats --no-stream`
|
||||
- **Logs**: `docker logs --tail 100 balotario-prod`
|
||||
|
||||
---
|
||||
|
||||
**Nota**: Esta configuración está optimizada para facilidad de uso y seguridad básica. Para producción enterprise, considera usar Kubernetes o Docker Swarm.
|
||||
95
docker/nginx.conf
Normal file
95
docker/nginx.conf
Normal file
@@ -0,0 +1,95 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Logging
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_types text/plain text/css text/xml text/javascript
|
||||
application/javascript application/xml+rss
|
||||
application/json application/xml;
|
||||
|
||||
# Rate limiting
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=static:10m rate=50r/s;
|
||||
|
||||
# Upstream para la aplicación Flask
|
||||
upstream balotario_app {
|
||||
server balotario:5000;
|
||||
}
|
||||
|
||||
# Servidor principal
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Archivos estáticos con cache
|
||||
location /static/ {
|
||||
limit_req zone=static burst=20 nodelay;
|
||||
proxy_pass http://balotario_app;
|
||||
proxy_cache_valid 200 1d;
|
||||
expires 1d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# API endpoints con rate limiting
|
||||
location /api/ {
|
||||
limit_req zone=api burst=5 nodelay;
|
||||
proxy_pass http://balotario_app;
|
||||
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;
|
||||
}
|
||||
|
||||
# Aplicación principal
|
||||
location / {
|
||||
proxy_pass http://balotario_app;
|
||||
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
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# Health check
|
||||
location /health {
|
||||
access_log off;
|
||||
proxy_pass http://balotario_app;
|
||||
}
|
||||
}
|
||||
|
||||
# Configuración HTTPS (opcional)
|
||||
# server {
|
||||
# listen 443 ssl http2;
|
||||
# server_name localhost;
|
||||
#
|
||||
# ssl_certificate /etc/nginx/ssl/cert.pem;
|
||||
# ssl_certificate_key /etc/nginx/ssl/key.pem;
|
||||
#
|
||||
# # Resto de configuración igual que HTTP
|
||||
# }
|
||||
}
|
||||
Reference in New Issue
Block a user