Guía de instalación Self-Hosted
Despliega MailDesk en tu propia infraestructura. Todos los datos permanecen en tus servidores.
Requisitos previos
| Requisito | Mínimo |
|---|---|
| Docker Engine 24+ | |
| Docker Compose v2.20+ | |
| 4 GB RAM | |
| 20 GB de disco (+ almacenamiento de adjuntos) | |
| Cualquier Linux con soporte Docker | |
| Clave de licencia de maildesk.cloud | |
1. Extraer y cargar
Extraer el paquete:
tar xzf maildesk-selfhosted.tar.gz
cd maildeskCargar las imágenes Docker:
docker load < maildesk-images.tar.gz2. Configurar entorno
./setup.shEjecuta ./setup.sh para auto-generar todos los secretos. Luego edita .env para configurar tu APP_URL y clave de licencia.
Abre .env y configura los siguientes valores:
Variables requeridas
| Variable | Descripción |
|---|---|
| APP_URL | URL pública de tu instancia (sin barra final) |
| MAILDESK_LICENSE_KEY | Tu clave de licencia JWT firmada con Ed25519 |
Auto-generado por setup.sh
Estos se generan automáticamente al ejecutar setup.sh. No cambiar excepto al migrar datos.
| Variable | Descripción |
|---|---|
| BETTER_AUTH_SECRET | Clave de firma de sesión, mín. 32 caracteres (auto-generada) |
| CREDENTIAL_ENCRYPTION_KEY | Clave AES-256-GCM para contraseñas IMAP/SMTP (auto-generada) |
| POSTGRES_PASSWORD | Contraseña de base de datos PostgreSQL (auto-generada) |
| REDIS_PASSWORD | Contraseña de caché Redis (auto-generada) |
| MAILDESK_MODE | Establecido a selfhosted (auto-configurado por setup.sh) |
Variables opcionales
| Variable | Descripción |
|---|---|
| MAILDESK_LICENSE_SERVER_URL | URL del servidor de licencias para verificación online (predeterminado: solo offline) |
| REGISTRATION_ENABLED | true (predeterminado) o false para desactivar auto-registro |
| ALLOWED_REGISTER_IPS | IPs separadas por coma con acceso a /register |
| ENABLE_HSTS | true para enviar encabezado HSTS (activar detrás de TLS) |
| LOG_LEVEL | trace, debug, info (predeterminado), warn, error, fatal |
| METRICS_AUTH_TOKEN | Token Bearer para el endpoint /api/metrics (oculto si no se configura) |
| OPENAI_EMBEDDING_KEY | Clave API de OpenAI para búsqueda semántica KB (opcional) |
| MAX_ATTACHMENT_SIZE_MB | Tamaño máximo de adjuntos en MB (predeterminado: 25) |
Ejemplo .env para self-hosted
# Only these 2 lines need manual editing after running ./setup.sh:
APP_URL=https://tickets.example.com
MAILDESK_LICENSE_KEY=eyJhbGciOiJFZERTQSIs...your-key-here
# Everything else is auto-generated by ./setup.sh3. Iniciar
docker compose up -dEsto inicia 6 servicios:
| Servicio | Propósito |
|---|---|
| migrate | Ejecuta migraciones de base de datos, luego termina |
| app | Aplicación web Next.js (puerto 3000) |
| worker | Worker en segundo plano (IMAP/SMTP, procesamiento de correo, tareas) |
| postgres | PostgreSQL 17 con extensión pgvector |
| redis | Redis 7 para colas de tareas y pub/sub |
| clamav | ClamAV antivirus para escaneo de adjuntos |
El servicio migrate se ejecuta automáticamente antes de que app y worker inicien. Crea todas las tablas de forma idempotente — seguro para bases de datos nuevas y existentes.
4. Verificar el despliegue
# Check all services are healthy
docker compose ps
# Check app logs
docker compose logs app
# Check worker logs
docker compose logs worker
# Health check endpoint
curl http://localhost:3000/api/healthUna vez healthy, abre tu APP_URL en un navegador. Deberías ver la página de login/registro.
5. Configuración inicial
- 1Registra la primera cuenta de administrador en tu-dominio.com/register
- 2Crea una organización — este es tu espacio de trabajo
- 3Añade un buzón en Configuración > Buzones (credenciales IMAP/SMTP)
- 4Los correos entrantes crearán tickets automáticamente
Verificación de Email (Opcional)
Configura SMTP para habilitar la verificación de email para nuevos usuarios. Sin SMTP, los nuevos usuarios se verifican automáticamente y pueden iniciar sesión de inmediato.
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=you@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM=MailDesk <noreply@yourdomain.com>Configuración de Reverse Proxy
MailDesk requiere un reverse proxy para terminación TLS. Aquí hay ejemplos para configuraciones comunes:
tickets.example.com {
handle /ws* {
reverse_proxy localhost:3002
}
handle {
reverse_proxy localhost:3000
}
}Clave de licencia
Tu clave de licencia es un JWT firmado con Ed25519 que contiene tu plan, límites y flags de funciones.
Qué controla la clave:
- Nivel de plan (Free, Pro, Business)
- Límites: máx. agentes, buzones, tickets/mes, almacenamiento
- Funciones: respuesta IA, base de conocimiento, traducción automática
Validación:
- La clave se valida offline por defecto usando la clave pública Ed25519 integrada — sin llamadas externas necesarias
- Si MAILDESK_LICENSE_SERVER_URL está configurado, MailDesk verificará la clave online periódicamente (opcional)
- Los datos de licencia validados se almacenan en caché en Redis durante 24 horas
- Si Redis no está disponible, el JWT se verifica directamente (Ed25519 no necesita servidor)
Clave expirada o inválida:
- La app entra en modo solo lectura — los datos existentes siguen accesibles
- Crear tickets, enviar respuestas y funciones de IA están desactivados
- Un banner muestra "Licencia expirada" con un enlace de renovación
Actualización
# Load new images
docker load < maildesk-images.tar.gz
# Restart (migrations run automatically)
docker compose up -dLas migraciones se ejecutan automáticamente en cada inicio — no se necesita paso de migración manual.
Backup y restauración
Backup
Base de datos
docker compose exec postgres pg_dump -U maildesk maildesk > backup_$(date +%Y%m%d).sqlAdjuntos
docker compose cp worker:/data/attachments ./attachments-backupRedis (opcional — solo cachés, se puede reconstruir)
docker compose exec redis redis-cli BGSAVERestauración
Base de datos
docker compose exec -T postgres psql -U maildesk maildesk < backup_20260317.sqlAdjuntos
docker compose cp ./attachments-backup/. worker:/data/attachmentsSolución de problemas
La app no inicia
docker compose logs app
docker compose logs migrateCausas comunes:
- Base de datos no lista — El servicio migrate espera el health check de Postgres. Revisa docker compose ps para servicios unhealthy.
- DATABASE_URL inválida — Asegúrate de que la cadena de conexión coincida con las credenciales de Postgres.
- Conflicto de puerto — Si el puerto 3000 está ocupado, cambia el mapeo de puertos en docker-compose.yml.
Errores de licencia
docker compose logs app | grep -i license- "License invalid" — Verifica que MAILDESK_LICENSE_KEY esté configurado correctamente en .env (sin saltos de línea, sin comillas alrededor del JWT).
- "License expired" — Renueva tu licencia en maildesk.cloud.
ClamAV tarda en iniciar
ClamAV descarga definiciones de virus en el primer inicio, lo que puede tardar 3–5 minutos.
docker compose logs clamavEl worker no procesa correos
docker compose logs worker- Verifica que las credenciales IMAP sean correctas en la configuración del buzón
- Comprueba que el servicio worker esté healthy
- Asegúrate de que Redis sea accesible
Vista general de la arquitectura
┌─────────────┐
│ Reverse │
│ Proxy │
│ (TLS) │
└──────┬──────┘
│ :3000
┌──────▼──────┐
│ App │
│ (Next.js) │
└──┬──────┬───┘
│ │
┌────────▼─┐ ┌─▼────────┐
│ Postgres │ │ Redis │
│ (pgvec) │ │ (queue) │
└────────▲─┘ └─▲────────┘
│ │
┌──┴──────┴───┐
│ Worker │
│ (IMAP/SMTP) │
└──────┬──────┘
│
┌──────▼──────┐
│ ClamAV │
│ (antivirus) │
└─────────────┘- App — App sirve la interfaz web y las rutas API
- Worker — Worker se conecta a buzones vía IMAP, envía respuestas vía SMTP, procesa tareas en segundo plano
- Postgres — Postgres almacena todos los datos de la aplicación (con pgvector para embeddings de IA)
- Redis — Redis gestiona colas de tareas (BullMQ) y pub/sub en tiempo real (WebSocket)
- ClamAV — ClamAV escanea adjuntos de correo en busca de malware