Despliegue¶
Docker Compose (Un contenedor — Servidor + Worker)¶
El despliegue más simple ejecuta servidor y worker en un solo proceso:
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: lapinq
POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme}
POSTGRES_DB: lapinq
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U lapinq"]
lapinq:
build:
context: .
dockerfile: Dockerfile.lapinq
command: python -m lapinq server --worker --cleanup-interval 300 --port 8001
ports:
- "8001:8001"
environment:
- DATABASE_URL=postgresql://lapinq:${DB_PASSWORD:-changeme}@db:5432/lapinq
depends_on:
db:
condition: service_healthy
volumes:
postgres_data:
Docker Compose (Worker separado — Producción)¶
Para producción, escala el worker independientemente:
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: lapinq
POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme}
POSTGRES_DB: lapinq
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U lapinq"]
lapinq:
build:
context: .
dockerfile: Dockerfile.lapinq
command: python -m lapinq server --port 8001
ports:
- "8001:8001"
environment:
- DATABASE_URL=postgresql://lapinq:${DB_PASSWORD:-changeme}@db:5432/lapinq
depends_on:
db:
condition: service_healthy
worker:
build:
context: .
dockerfile: Dockerfile.lapinq
command: lapinq-worker --database-url postgresql://lapinq:${DB_PASSWORD:-changeme}@db:5432/lapinq --concurrency 4
environment:
- DATABASE_URL=postgresql://lapinq:${DB_PASSWORD:-changeme}@db:5432/lapinq
deploy:
replicas: 2
depends_on:
db:
condition: service_healthy
volumes:
postgres_data:
Consideraciones de Producción¶
PostgreSQL¶
- Usa un servicio gestionado (RDS, Cloud SQL, etc.) para producción
- Activa connection pooling (PgBouncer) para alta concurrencia
- Configura
max_connectionsadecuadamente
Configuración del Worker¶
--concurrency: Ajusta a los núcleos de CPU (normalmente 2-4 por worker)--task-timeout: Evita tareas sin fin (por defecto 300s)--cleanup-interval: Configura a 300s o más para limpieza TTL- Ejecuta múltiples réplicas del worker para alto rendimiento
Escalado¶
Cada worker reclama tareas independientemente usando FOR UPDATE SKIP LOCKED, por lo que escalan horizontalmente sin coordinación.
# Ejecuta múltiples workers Rust
lapinq-worker --database-url $DATABASE_URL --concurrency 4
lapinq-worker --database-url $DATABASE_URL --concurrency 4
Autenticación y Rate Limiting¶
API Key (acceso programático)¶
Todas las rutas /api/* requieren la cabecera X-API-Key.
Autenticación del Dashboard¶
El dashboard usa autenticación por sesión. Un usuario admin por defecto lapinq/lapinq se crea automáticamente en el primer inicio.
Establece un secreto de sesión fijo para mantener las sesiones activas tras reinicios:
Sin esto, se genera un secreto aleatorio en cada inicio, invalidando todas las sesiones activas.
Roles de Usuario¶
- Admin: Acceso completo — ver dashboard, eliminar tareas, cancelar/reencolar, crear usuarios, gestionar permisos.
- User: Solo lectura por defecto — puede ver el dashboard y cambiar su propia contraseña. Los admins pueden conceder permisos por cola (delete, cancel) según sea necesario.
Rate Limiting¶
Limita peticiones por IP por minuto en rutas /api/*
Monitoreo¶
- Dashboard en
http://localhost:8001 - Health check:
GET /health - Métricas Prometheus:
GET /metrics - Estadísticas de colas:
GET /api/v1/queues - DLQ (Dead Letter Queue):
GET /api/v1/tasks/failed