Tutoriales de VPS
Instalar Mailcow en un VPS (2026): Docker, DNS, antispam, copias de seguridad y entregabilidad
Instala el servidor de correo autoalojado Mailcow en un VPS, con configuración completa de Docker, PTR, SPF, DKIM, DMARC, TLS, antispam, copias de seguridad externas, actualizaciones y diagnóstico de entregabilidad.

Si quieres enviar y recibir correo con tu propio dominio sin instalar por separado Postfix, Dovecot, Rspamd, webmail y servicios de certificados, Mailcow es una de las suites de correo autoalojadas más completas disponibles. Combina SMTP, IMAP, webmail SOGo, antispam, análisis de virus, DKIM y un panel de administración en un único proyecto de Docker Compose.
Pero un servidor de correo no es algo que "funciona en cuanto arrancan los contenedores". El puerto 25 del VPS, una IP pública dedicada, el PTR de resolución inversa y la reputación histórica de la IP suelen importar más que el rendimiento de la CPU. Si eliges la máquina equivocada, el correo enviado a Gmail, Outlook o buzones corporativos puede seguir siendo rechazado o acabar en spam aunque el panel de administración esté todo en verde.
Este tutorial empieza con las comprobaciones que hay que hacer antes de comprar un VPS, usa el repositorio oficial de Mailcow mailcow-dockerized para completar la instalación, configura A, MX, PTR, SPF, DKIM, DMARC, TLS, antispam, copias de seguridad y actualizaciones, y ofrece una lista de verificación de entregabilidad y resolución de problemas habituales.
Mailcow es una suite completa de correo y colaboración, no un reenviador SMTP ligero.
| Necesidad | ¿Es adecuado Mailcow? | Motivo |
|---|---|---|
| Un equipo pequeño que usa buzones, calendarios y contactos en su propio dominio | Adecuado | Incluye SOGo, IMAP, SMTP, capacidades relacionadas con ActiveSync y un panel de administración unificado |
| Necesidad de controlar los datos de los buzones, el archivado y el ciclo de vida de las cuentas | Adecuado | Los datos permanecen en tu propio VPS y en los volúmenes de Docker |
| Un sitio web que solo necesita enviar códigos de verificación y correos de notificación | Normalmente no adecuado | Un servicio de correo transaccional dedicado requiere menos mantenimiento y construye reputación de envío con más facilidad |
| Correo masivo de marketing, correo en frío | No adecuado | Daña fácilmente la reputación de la IP y del dominio, y puede infringir los términos de servicio del VPS |
| Un VPS en el que no puedes obtener un PTR ni abrir el puerto 25 | No adecuado | Los servidores de correo externos pueden rechazar directamente o bajar tu reputación |
Si solo necesitas enviar notificaciones para Ghost, WordPress o un sistema de negocio y no necesitas buzones para empleados, prioriza servicios de correo transaccional como Amazon SES, Postmark o Mailgun. Mailcow encaja mejor en equipos que realmente necesitan buzones completos, webmail, calendarios y gestión de dominios.
Primero lee la Política de Uso Aceptable del proveedor y confirma con el soporte que se permiten servidores de correo autoalojados. Algunos VPS baratos prohíben los servicios de correo o bloquean de forma permanente el TCP 25 saliente por defecto.
"Puedes abrir el 25 en el grupo de seguridad" no significa que la red ascendente permita el tráfico saliente. Pregunta explícitamente antes de comprar:
- Si está abierto el TCP 25 entrante;
- Si está abierto el TCP 25 saliente y si requiere una solicitud de desbloqueo;
- Si hay restricciones en puertos como 465, 587, 993, 80 y 443;
- Si hay periodos de espera o requisitos de KYC para cuentas nuevas.
Si el proveedor solo puede abrir el 587, eso sigue sin sustituir el puerto 25 necesario para la entrega entre servidores.
El PTR de la IPv4 pública debe configurarlo el proveedor de VPS/IP con el nombre de host de Mailcow, por ejemplo:
203.0.113.10 -> mail.example.com
Al mismo tiempo, el registro A de mail.example.com debe resolver hacia la misma IP. Una discrepancia entre directo e inverso es una causa habitual de que el correo acabe en spam o sea rechazado.
Tras obtener la IP, comprueba primero las listas negras en tiempo real habituales y los registros históricos de abuso. Si la IP ya tiene una reputación grave de spam, la opción que ahorra más tiempo suele ser pedir al proveedor que cambie la IP, en lugar de intentar "limpiarla" poco a poco con un dominio nuevo.
Para seguir diagnosticando rechazos, la llegada a la carpeta de spam y los resultados de autenticación, usa esto junto con la guía de diagnóstico de entregabilidad de correo autoalojado en VPS.
El mínimo oficial de Mailcow para la configuración por defecto es 6GiB de memoria más 1GiB de Swap, con al menos 20GiB de disco sin incluir los datos de correo; la recomendación oficial es 8GiB de memoria para unos 5 a 10 usuarios. ClamAV y la búsqueda de texto completo consumen bastante memoria.
| Caso de uso | Configuración de VPS recomendada | Notas |
|---|---|---|
| Personal o hasta 3 buzones | 4 núcleos, 8GB, 80GB SSD | Mantén ClamAV y la búsqueda de texto completo, y reserva espacio para el sistema y las copias de seguridad |
| 5-10 usuarios | 4 núcleos, 8-16GB, 160GB SSD | Amplía según los adjuntos, el periodo de retención y las conexiones móviles |
| Unos 50 IMAP concurrentes, varios dispositivos ActiveSync | 8 núcleos, 16GB o más | El ejemplo oficial recomienda 16GiB; haz una evaluación de capacidad antes de desplegar |
| Menos de 6GB de memoria | Configuración por defecto no recomendada | Incluso con ClamAV/FTS desactivados, reduce funciones y margen de seguridad |
No mires solo el número de buzones. Las conexiones móviles de larga duración, la indexación de texto completo, los adjuntos grandes, el entrenamiento antispam y las copias de seguridad también afectan a los recursos. Si aún no has decidido las especificaciones de la máquina, consulta primero la guía de selección de configuración de VPS.
La virtualización debe ser completa, como KVM, ESX o Hyper-V. Mailcow no admite oficialmente VPS basados en contenedores OpenVZ, Virtuozzo o LXC. El sistema usado como ejemplo es Ubuntu 24.04 LTS, x86_64.
Este artículo usa el siguiente ejemplo:
邮件域名:example.com
Mailcow 主机名:mail.example.com
服务器 IPv4:203.0.113.10
El nombre de host debe ser un nombre de dominio completo, no solo mail, y no deberías usar directamente el dominio raíz example.com. Si el DNS está alojado en Cloudflare, mail.example.com debe configurarse como DNS only y no debe tener activado el proxy de nube naranja, porque el proxy normal de Cloudflare no reenvía puertos de correo como SMTP e IMAP.
Configura el nombre de host y la zona horaria del servidor antes de la instalación:
sudo hostnamectl set-hostname mail.example.com
sudo timedatectl set-timezone Asia/Shanghai
hostname -f
timedatectl status
Una hora incorrecta afecta a TLS, a la correlación de registros y a la autenticación de dos factores TOTP, así que no se puede omitir.
Mailcow usa estos puertos TCP por defecto:
| Puerto | Uso |
|---|---|
| 25 | Entrega SMTP entre servidores de correo |
| 465 / 587 | Envío cifrado desde clientes de correo |
| 143 / 993 | IMAP / IMAPS |
| 110 / 995 | POP3 / POP3S |
| 4190 | Reglas de filtro ManageSieve |
| 80 / 443 | Panel de administración, webmail, validación de certificados |
Antes de instalar, comprueba si Nginx, Apache, Postfix u otros servicios ya ocupan los puertos:
sudo ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'
Lo ideal es que la salida esté vacía. Mailcow incluye su propio Nginx y componentes de certificados, así que para una primera instalación no se recomienda añadir encima Caddy o Nginx Proxy Manager. Si un sitio web existente ocupa el 80/443, ajusta los puertos vinculados según la documentación oficial de proxy inverso de Mailcow, en lugar de editar sin cuidado el archivo Compose.
Mailcow requiere actualmente Docker Engine 24.0 o superior y Docker Compose 2.0 o superior. Instala desde el repositorio oficial de Docker, no desde paquetes de la distribución desactualizados durante años.
Instala las herramientas que necesita Mailcow:
sudo apt update
sudo apt install -y git openssl curl gawk coreutils grep jq
docker --version
docker compose version
Para los registros de Docker, el espacio en disco y los principios de reversión en producción, consulta la lista de verificación de configuración de producción de Docker Compose en VPS. No edites directamente docker-compose.yml, que Mailcow mantiene automáticamente; usa el método de configuración oficialmente admitido para las personalizaciones.
Clona el repositorio oficial y genera la configuración:
sudo -i
umask 0022
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh
Cuando el script pregunte por el nombre de host, introduce:
mail.example.com
Luego revisa los elementos clave de /opt/mailcow-dockerized/mailcow.conf:
MAILCOW_HOSTNAME=mail.example.com
TZ=Asia/Shanghai
SKIP_LETS_ENCRYPT=n
SKIP_CLAMD=n
SKIP_FTS=n
ENABLE_IPV6=false
Configura ENABLE_IPV6 como true solo si el VPS tiene correctamente configurados IPv6 público, AAAA y PTR de IPv6. Forzarlo sin una ruta de correo IPv6 completa puede hacer que algunas entregas salgan desde IPv6 que nunca ha construido reputación.
generate_config.sh genera configuración aleatoria como contraseñas de base de datos; no subas mailcow.conf a un repositorio Git público.
Inicia los servicios:
docker compose pull
docker compose up -d
docker compose ps
Mailcow incluye varios contenedores, y la primera descarga e inicialización tardan unos minutos. No compruebes solo si un contenedor está Up; revisa todos los servicios principales:
docker compose ps
docker compose logs --tail=100 nginx-mailcow
docker compose logs --tail=100 postfix-mailcow
docker compose logs --tail=100 dovecot-mailcow
docker compose logs --tail=100 acme-mailcow
Primero crea los registros que permiten que el servidor esté en línea y reciba correo. Los nombres de campo varían ligeramente entre consolas DNS:
mail A 203.0.113.10
@ MX 10 mail.example.com.
autodiscover CNAME mail.example.com.
autoconfig CNAME mail.example.com.
@ TXT "v=spf1 mx a -all"
_dmarc TXT "v=DMARC1; p=none; rua=mailto:[email protected]"
También configura lo siguiente en la consola del proveedor del VPS:
PTR 203.0.113.10 -> mail.example.com
Empieza con p=none para recopilar informes DMARC y, tras confirmar que todas las fuentes legítimas pasan la alineación SPF o DKIM, cambia gradualmente a quarantine o reject. Si el dominio también envía correo mediante servicios de terceros, no copies v=spf1 mx a -all tal cual; debes fusionar todas las fuentes de envío legítimas en un único registro SPF.
Tras la propagación del DNS, comprueba:
dig +short A mail.example.com
dig +short MX example.com
dig +short TXT example.com
dig +short TXT _dmarc.example.com
dig +short -x 203.0.113.10
A y PTR deben corresponderse entre sí, y el destino MX debe ser un nombre de host, no una IP.
Abre en el navegador:
https://mail.example.com/admin
La cuenta inicial oficial es admin y la contraseña por defecto es moohoo. Inmediatamente después del primer inicio de sesión:
- Cambia la contraseña del administrador;
- Activa la autenticación de dos factores;
- Crea un segundo administrador controlado como vía de recuperación;
- Confirma que el certificado TLS se ha emitido y que el navegador no muestra advertencias;
- No permitas que las cuentas de buzón normales tengan privilegios de administración innecesarios.
Si el panel de administración ya es accesible desde internet pero aún no has cambiado la contraseña por defecto, restringe el acceso antes de continuar con la configuración.
En el panel de administración de Mailcow, completa lo siguiente en orden:
- Configuration → Mail Setup → Domains, añade
example.com; - Crea los buzones necesarios, como
[email protected]y[email protected]; - Genera una DKIM Key para el dominio;
- Copia el valor TXT completo de DKIM que muestra el panel al DNS;
- Tras la propagación, vuelve a ejecutar la comprobación de DNS en el panel.
El registro DKIM suele ser similar a:
dkim._domainkey TXT "v=DKIM1; k=rsa; p=这里使用后台生成的公钥"
No inventes a mano la clave pública después de p= ni pongas la clave privada en el DNS. Si el registro es demasiado largo, el proveedor de DNS puede dividirlo automáticamente en varias cadenas; siempre que la consulta TXT final pueda reconstruir el valor completo, es correcto.
Los puertos publicados por Docker pasan por la cadena de reenvío. Mailcow advierte oficialmente de que escribir solo reglas UFW/INPUT puede no restringir los puertos de los contenedores; las restricciones deben colocarse en DOCKER-USER o en un cortafuegos en la nube externo.
Un servidor de correo debe permitir al menos los puertos públicos que realmente se necesitan. Si el panel de administración es solo para uso del equipo, puedes restringir las IP de origen en el cortafuegos ascendente; el SMTP 25 y los puertos de protocolo de correo que usan los destinatarios no deben bloquearse por error.
Tras aplicar las reglas, prueba realmente desde otra máquina en lugar de comprobar solo localmente:
nc -vz mail.example.com 25
nc -vz mail.example.com 443
nc -vz mail.example.com 587
nc -vz mail.example.com 993
openssl s_client -starttls smtp -connect mail.example.com:25 \
-servername mail.example.com </dev/null
Los cortafuegos en la nube, las reglas del host y las cadenas de Docker deben comprobarse juntos. No vacíes en bloque las reglas de iptables en una sesión SSH remota.
Antes de migrar formalmente los buzones del dominio, completa al menos cuatro rondas de pruebas:
Envía correo desde Gmail, Outlook u otro buzón externo a [email protected] y confirma que llega a SOGo y al cliente IMAP.
Envía por separado a Gmail, Outlook y otro buzón corporativo, y comprueba si el correo llega a la bandeja de entrada. No envíes solo entre buzones del mismo dominio, ya que eso no pasa por la ruta real de entrega en internet.
En el lado del destinatario, revisa las cabeceras del mensaje original y confirma:
spf=pass
dkim=pass
dmarc=pass
Que los tres pasen sigue sin garantizar la llegada a la bandeja de entrada; la reputación de la IP, el contenido, el ritmo de envío y los comentarios de los usuarios también influyen en el resultado.
cd /opt/mailcow-dockerized
docker compose logs --since=30m postfix-mailcow
docker compose logs --since=30m rspamd-mailcow
docker compose exec postfix-mailcow postqueue -p
Cuando encuentres timeout, connection refused, blocked using o 550 5.7.x, conserva la respuesta completa del par antes de actuar, y no reenvíes repetidamente creando más señales negativas.
Mailcow ofrece oficialmente helper-scripts/backup_and_restore.sh, que puede hacer copia de seguridad del correo, las bases de datos, el material de cifrado, Redis, Rspamd y los datos de Postfix. No copies el script a otro lugar; ejecútalo directamente en el repositorio:
sudo mkdir -p /opt/mailcow-backups
cd /opt/mailcow-dockerized
MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups \
./helper-scripts/backup_and_restore.sh backup all --delete-days 7
Tras revisar el directorio de copias de seguridad generado y los registros, configura Cron:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
30 3 * * * cd /opt/mailcow-dockerized && MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups ./helper-scripts/backup_and_restore.sh backup all --delete-days 7 >> /var/log/mailcow-backup.log 2>&1
/opt/mailcow-backups sigue en el mismo VPS, así que solo protege contra el borrado accidental, no contra fallos de disco o suspensión de la cuenta. Sincroniza las copias de seguridad cifradas con otro almacenamiento de objetos o un servidor externo, y restaura periódicamente usando una máquina de prueba en blanco. Puedes reutilizar los métodos de verificación, retención y aceptación de restauración de la guía de simulacros de copia de seguridad y restauración en VPS.
Los criterios de una restauración correcta incluyen: que el administrador pueda iniciar sesión, que el correo histórico y los adjuntos estén completos, que existan la configuración del dominio y de DKIM, y que el envío y la recepción funcionen; no que el código de salida del script sea 0.
Mailcow está formado por varios servicios de red, y las actualizaciones de seguridad no pueden retrasarse mucho. El repositorio oficial ofrece update.sh; no hagas actualizaciones no planificadas de cada imagen por tu cuenta.
Proceso de actualización:
cd /opt/mailcow-dockerized
./update.sh --check
# 先执行完整备份并确认异地副本可读
./update.sh
docker compose ps
docker compose logs --tail=100 nginx-mailcow
docker compose logs --tail=100 postfix-mailcow
docker compose logs --tail=100 dovecot-mailcow
Tras actualizar, verifica el panel de administración, SOGo, el inicio de sesión IMAP, el envío SMTP, el envío y la recepción externos, la cola, TLS y DKIM. Mantén la rama stable en producción y no cambies directamente a nightly.
dig +short MX example.com
nc -vz mail.example.com 25
docker compose logs --tail=200 postfix-mailcow
Primero confirma que el MX apunta al nombre de host correcto, que el registro A apunta a la IP actual y que el 25 entrante está abierto. La nube naranja de Cloudflare, los MX antiguos y el bloqueo del operador pueden causar tiempos de espera.
nc -vz gmail-smtp-in.l.google.com 25
docker compose exec postfix-mailcow postqueue -p
docker compose logs --tail=300 postfix-mailcow
Si todas las conexiones externas al puerto 25 dan tiempo de espera, contacta primero con el proveedor del VPS para confirmar el bloqueo saliente. No confundas el puerto 587 de envío del cliente con el puerto 25 de entrega del servidor.
Comprueba el directo e inverso de A/PTR, SPF, DKIM, DMARC, las listas negras de IP y las cabeceras originales del mensaje. No empieces a enviar en masa de repente desde una IP nueva; primero construye reputación gradualmente con comunicación de negocio real uno a uno. Para códigos de error y diagnóstico de entrega más completos, consulta la guía de entregabilidad de correo enlazada antes.
dig +short A mail.example.com
docker compose logs --tail=300 acme-mailcow
sudo ss -lntp | grep -E ':80|:443'
Confirma que el dominio resuelve directamente al VPS de Mailcow, que el 80/443 es accesible y no está ocupado por otros servicios. Si IPv6 no está configurado correctamente, elimina el AAAA incorrecto y desactiva IPv6 en Mailcow.
free -h
docker stats --no-stream
docker compose ps
journalctl -k --since '1 hour ago' | grep -i -E 'oom|killed process'
Con la configuración por defecto por debajo de 6GiB de memoria, la prioridad es ampliar el VPS. En una emergencia puedes configurar SKIP_CLAMD=y y SKIP_FTS=y según las instrucciones oficiales, pero esto desactiva el análisis de virus o la búsqueda de texto completo y no debe presentarse como una optimización sin coste.
Prioriza 993 IMAPS y 587 Submission, y confirma que el nombre de usuario es la dirección de correo completa. Comprueba la hora, el certificado, la contraseña y los registros de Dovecot:
docker compose logs --since=30m dovecot-mailcow
openssl s_client -connect mail.example.com:993 \
-servername mail.example.com </dev/null
- El VPS permite servicios de correo, y el TCP 25 entrante/saliente se ha probado
- Se usa virtualización admitida como KVM, con la configuración por defecto de al menos 6GiB de memoria más 1GiB de Swap
- El registro A de
mail.example.comy el PTR de la IP pública coinciden en directo e inverso - MX, SPF, DKIM, DMARC, autodiscover y autoconfig se han resuelto
- Los registros DNS no están proxificados por un CDN normal
- La contraseña por defecto del administrador se ha cambiado y la autenticación de dos factores está activada
- El certificado TLS es válido, y los puertos SMTP, IMAPS y Submission son accesibles
- La recepción externa y el envío a varios servicios se han probado con éxito
- SPF, DKIM y DMARC pasan en las cabeceras de mensajes reales
- Las copias de seguridad completas se han copiado fuera del sitio y se ha completado un simulacro de restauración en máquina en blanco
- Se han registrado el proceso de actualización, las ubicaciones de los registros y los contactos de incidencias
Mailcow reduce la barrera para instalar componentes y para la gestión diaria, pero no puede resolver por ti la reputación de la IP, la propiedad del DNS ni el cumplimiento del correo. Comprobar primero el puerto 25, el PTR y el historial de la IP, y luego desplegar y migrar los buzones de producción, suele ahorrar más tiempo que instalar primero y luego reclamar por todas partes.