Guía de instalación Self-Hosted

Despliega MailDesk en tu propia infraestructura. Todos los datos permanecen en tus servidores.

Requisitos previos

RequisitoMí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
La app escucha en el puerto 3000 por defecto. Coloca un reverse proxy (Caddy, Nginx, Traefik) delante para TLS.

1. Extraer y cargar

Extraer el paquete:

shell
tar xzf maildesk-selfhosted.tar.gz
cd maildesk

Cargar las imágenes Docker:

shell
docker load < maildesk-images.tar.gz

2. Configurar entorno

shell
./setup.sh

Ejecuta ./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

VariableDescripción
APP_URLURL pública de tu instancia (sin barra final)
MAILDESK_LICENSE_KEYTu 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.

VariableDescripción
BETTER_AUTH_SECRETClave de firma de sesión, mín. 32 caracteres (auto-generada)
CREDENTIAL_ENCRYPTION_KEYClave AES-256-GCM para contraseñas IMAP/SMTP (auto-generada)
POSTGRES_PASSWORDContraseña de base de datos PostgreSQL (auto-generada)
REDIS_PASSWORDContraseña de caché Redis (auto-generada)
MAILDESK_MODEEstablecido a selfhosted (auto-configurado por setup.sh)

Variables opcionales

VariableDescripción
MAILDESK_LICENSE_SERVER_URLURL del servidor de licencias para verificación online (predeterminado: solo offline)
REGISTRATION_ENABLEDtrue (predeterminado) o false para desactivar auto-registro
ALLOWED_REGISTER_IPSIPs separadas por coma con acceso a /register
ENABLE_HSTStrue para enviar encabezado HSTS (activar detrás de TLS)
LOG_LEVELtrace, debug, info (predeterminado), warn, error, fatal
METRICS_AUTH_TOKENToken Bearer para el endpoint /api/metrics (oculto si no se configura)
OPENAI_EMBEDDING_KEYClave API de OpenAI para búsqueda semántica KB (opcional)
MAX_ATTACHMENT_SIZE_MBTamaño máximo de adjuntos en MB (predeterminado: 25)

Ejemplo .env para self-hosted

env
# 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.sh

3. Iniciar

shell
docker compose up -d

Esto inicia 6 servicios:

ServicioPropósito
migrateEjecuta migraciones de base de datos, luego termina
appAplicación web Next.js (puerto 3000)
workerWorker en segundo plano (IMAP/SMTP, procesamiento de correo, tareas)
postgresPostgreSQL 17 con extensión pgvector
redisRedis 7 para colas de tareas y pub/sub
clamavClamAV 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

shell
# 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/health

Una vez healthy, abre tu APP_URL en un navegador. Deberías ver la página de login/registro.

5. Configuración inicial

  1. 1Registra la primera cuenta de administrador en tu-dominio.com/register
  2. 2Crea una organización — este es tu espacio de trabajo
  3. 3Añade un buzón en Configuración > Buzones (credenciales IMAP/SMTP)
  4. 4Los correos entrantes crearán tickets automáticamente
Tip: Usa ALLOWED_REGISTER_IPS para restringir quién puede crear cuentas, o establece REGISTRATION_ENABLED=false después de crear la cuenta de administrador.

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.

.env
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=you@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM=MailDesk <noreply@yourdomain.com>
Sin SMTP: La verificación de email se omite automáticamente. Los nuevos usuarios pueden registrarse e iniciar sesión sin confirmar su email. Puedes agregar SMTP en cualquier momento.

Configuración de Reverse Proxy

MailDesk requiere un reverse proxy para terminación TLS. Aquí hay ejemplos para configuraciones comunes:

Caddyfile
tickets.example.com {
    handle /ws* {
        reverse_proxy localhost:3002
    }
    handle {
        reverse_proxy localhost:3000
    }
}
WebSocket: MailDesk usa WebSocket para actualizaciones en tiempo real (chat, notificaciones, eventos de tickets). La ruta /ws debe apuntar al puerto 3002 (worker).

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

shell
# Load new images
docker load < maildesk-images.tar.gz

# Restart (migrations run automatically)
docker compose up -d

Las migraciones se ejecutan automáticamente en cada inicio — no se necesita paso de migración manual.

Backup y restauración

Backup

Base de datos

shell
docker compose exec postgres pg_dump -U maildesk maildesk > backup_$(date +%Y%m%d).sql

Adjuntos

shell
docker compose cp worker:/data/attachments ./attachments-backup

Redis (opcional — solo cachés, se puede reconstruir)

shell
docker compose exec redis redis-cli BGSAVE

Restauración

Base de datos

shell
docker compose exec -T postgres psql -U maildesk maildesk < backup_20260317.sql

Adjuntos

shell
docker compose cp ./attachments-backup/. worker:/data/attachments

Solución de problemas

La app no inicia

shell
docker compose logs app
docker compose logs migrate

Causas 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

shell
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.

shell
docker compose logs clamav

El worker no procesa correos

shell
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