
Um guia prático para instalar e configurar o servidor Stalwart no Coolify, cobrindo DNS, TLS, DKIM, SPF, DMARC e boas práticas de segurança.
Introdução
Nos últimos dias venho rodando um servidor de e-mail com Stalwart dentro do Coolify e obtive nota máxima nos testes do top.nic.br. Neste artigo vou mostrar, em primeira mão, como cheguei lá. Os passos práticos para implantar o servidor no Coolify, quais registros DNS são necessários e as melhores práticas de segurança para manter a entrega e a reputação do seu domínio.
Muitos desenvolvedores e administradores ficam frustrados com a complexidade de configurar um servidor de e-mail moderno e seguro. Eu passei por esse processo e documentei as etapas que funcionaram no meu caso, desde a criação do serviço no Coolify até a validação final das políticas SPF/DKIM/DMARC e do TLS.
Visão geral do que será abordado
- Pré-requisitos e preparação do ambiente
- Deploy do Stalwart no Coolify (passo a passo)
- Configuração de DNS: MX, SPF, DKIM e DMARC
- Hardening e boas práticas de segurança
- Testes e validação (incluindo top.nic.br)
Pré-requisitos
Antes de começar, garanta:
- Um servidor com acesso SSH onde o Coolify está instalado (ou acesso ao painel do Coolify hospedado).
- Um domínio com acesso para editar registros DNS (zona DNS gerenciada pelo seu provedor ou Cloud DNS).
- Conta ou acesso ao painel do Coolify com permissão para criar apps/containers.
- Conhecimento básico de DNS e TLS. Vou apontar links oficiais quando necessário.
Onde buscar documentação
Consulte sempre a documentação oficial do projeto: Documentação de segurança do Stalwart e a documentação do Coolify. Essas fontes ajudam a manter as configurações atualizadas.
Preparando o Servidor
Primeiro você precisa habilitar conexões TCP em algumas portas referentes ao serviço de e-mail, sendo elas:
- Porta 25: SMTP (Simple Mail Transfer Protocol) para envio e recebimento de e-mails entre servidores (MTA-to-MTA).
- Porta 587: SMTP Submission para envio autenticado de e-mails por clientes (MUAs) com STARTTLS.
- Porta 465: SMTPS (SMTP sobre TLS implícito) para envio autenticado de e-mails com criptografia desde a conexão inicial.
- Porta 143: IMAP para acesso e sincronização de caixas de e-mail sem criptografia (pode usar STARTTLS).
- Porta 993: IMAPS (IMAP sobre TLS implícito) para acesso seguro e criptografado às caixas de e-mail.
- Porta 4190 (opcional): ManageSieve para gerenciamento remoto de filtros de e-mail Sieve no servidor.
- Porta 110: POP3 para download de e-mails sem criptografia (geralmente remove do servidor após baixar).
- Porta 995: POP3S (POP3 sobre TLS implícito) para download seguro e criptografado de e-mails.
💡
Você pode optar por não utilizar o serviço IMAP ou não utilizar o POP3, mas eu acho interessante deixar as 2 habilitadas, pois aí fica a cargo do usuário escolher qual ele deseja utilizar. Mas o IMAP é o mais comum, pois as mensagens ficam salvas no servidor, permitindo que você sincronize os dados entre vários dispositivos.
Configuração de DNS (passo a passo)
Para obter boa entregabilidade e nota máxima em testes como o do top.nic.br, configure corretamente estes registros:
| Registro | Nome | Dados |
|---|---|---|
| A | mail.YOUR_DOMAIN | Endereço IPv4 público do seu servidor. |
| AAAA | mail.YOUR_DOMAIN | Endereço IPv6 do seu servidor. |
| MX | YOUR_DOMAIN | “10 mail.YOUR_DOMAIN” |
| SPF (TXT) | YOUR_DOMAIN | “v=spf1 mx ra=postmaster -all” |
| SPF (TXT) | mail.YOUR_DOMAIN | “v=spf1 a ra=postmaster -all” |
| CNAME | autoconfig.YOUR_DOMAIN | mail.cienciaembarcada.com.br |
| CNAME | autodiscover.YOUR_DOMAIN | mail.cienciaembarcada.com.br |
| CNAME | mta-sts.YOUR_DOMAIN | Endereço do seu servidor Coolify |
| MTA-STS (TXT) | _mta-sts.YOUR_DOMAIN | “v=STSv1; id=20260213” O ID é mantido por você. Atualize conforme atualizar o MTA-STS |
| SMTP (TXT) | _smtp._tls.YOUR_DOMAIN | “v=TLSRPTv1; rua=mailto:postmaster@YOUR_DOMAIN” |
| DMARC (TXT) | _dmarc.YOUR_DOMAIN | “v=DMARC1; p=reject; rua=mailto:postmaster@YOUR_DOMAIN; ruf=mailto:postmaster@YOUR_DOMAIN” |
Preparando o Proxy do Coolify (Traefik)
Para garantir o funcionamento e permitir que o Stalwart importe os certificados TLS gerados automaticamente pelo Coolify, é muito importante que você edite o docker-compose.yml do proxy, nesse caso, o Traefik:
name: coolify-proxy
networks:
coolify:
external: true
services:
traefik:
container_name: coolify-proxy
image: 'traefik:v3.6'
restart: unless-stopped
extra_hosts:
- 'host.docker.internal:host-gateway'
networks:
- coolify
ports:
- '80:80'
- '443:443'
- '443:443/udp'
- '8080:8080'
healthcheck:
test: 'wget -qO- http://localhost:80/ping || exit 1'
interval: 4s
timeout: 2s
retries: 5
volumes:
- '/var/run/docker.sock:/var/run/docker.sock:ro'
- '/data/coolify/proxy/:/traefik'
- '/etc/localtime:/etc/localtime:ro'
- '/etc/traefik:/etc/traefik'
command:
- '--ping=true'
- '--ping.entrypoint=http'
- '--api.dashboard=true'
- '--api.insecure=false'
# Entrypoints HTTP/HTTPS
- '--entrypoints.http.address=:80'
- '--entrypoints.https.address=:443'
- '--entrypoints.http.http.encodequerysemicolons=true'
- '--entryPoints.http.http2.maxConcurrentStreams=250'
- '--entrypoints.https.http.encodequerysemicolons=true'
- '--entryPoints.https.http2.maxConcurrentStreams=250'
- '--entrypoints.https.http3'
# Providers
- '--providers.docker=true'
- '--providers.docker.exposedbydefault=false'
- '--providers.file.directory=/traefik/dynamic/'
- '--providers.file.watch=true'
# Let's Encrypt
- '--certificatesresolvers.letsencrypt.acme.httpchallenge=true'
- '--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json'
- '--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http'
labels:
- traefik.enable=true
- traefik.http.routers.traefik.entrypoints=http
- traefik.http.routers.traefik.service=api@internal
- traefik.http.services.traefik.loadbalancer.server.port=8080
- coolify.managed=true
- coolify.proxy=true
traefik-certs-dumper:
image: ghcr.io/kereis/traefik-certs-dumper:latest
container_name: traefik-certs-dumper
restart: unless-stopped
depends_on:
- traefik
networks:
- coolify
volumes:
- '/etc/localtime:/etc/localtime:ro'
- '/data/coolify/proxy:/traefik:ro'
- '/data/coolify/certs:/output'
mta-sts-nginx:
image: nginx:alpine
container_name: mta-sts-server
restart: unless-stopped
networks:
- coolify
volumes:
- '/data/mta-sts:/usr/share/nginx/html:ro'
labels:
- traefik.enable=true
# Router HTTP (para HTTP challenge do Let's Encrypt)
- traefik.http.routers.mta-sts-http.rule=Host(`mta-sts.YOUR_DOMAIN`)
- traefik.http.routers.mta-sts-http.entrypoints=http
- traefik.http.routers.mta-sts-http.middlewares=mta-sts-redirect
# Router HTTPS
- traefik.http.routers.mta-sts.rule=Host(`mta-sts.YOUR_DOMAIN`)
- traefik.http.routers.mta-sts.entrypoints=https
- traefik.http.routers.mta-sts.tls=true
- traefik.http.routers.mta-sts.tls.certresolver=letsencrypt
# Middleware de redirecionamento HTTPS
- traefik.http.middlewares.mta-sts-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.mta-sts-redirect.redirectscheme.permanent=true
# Service
- traefik.http.services.mta-sts.loadbalancer.server.port=80Perceba que é necessária a criação de outros 2 serviços, o traefik-certs-dumper, utilizado para copiar os certificados para uma pasta que será acessada pelo Stalwart, e o mta-sts-nginx, que é um servidor nginx para expor o arquivo de MTA-STS. Após realizar a alteração no docker-compose.yml do proxy, basta reiniciar ele.
Configurando o Arquivo do MTA-STS
Agora é muito importante que você acesse a pasta /data/mta-sts/ e crie uma pasta chamada .well-known. Dentro dessa pasta você deve criar um arquivo chamado mta-sts.txt com o seguinte conteúdo:
version: STSv1 mode: enforce mx: mail.YOUR_DOMAIN max_age: 86400
O arquivo final deve estar em /data/mta-sts/.well-known/mta-sts.txt.
Deploy do Stalwart no Coolify
O Coolify facilita o deploy com Docker/Compose. Eu prefiro criar um novo aplicativo no painel do Coolify e apontar para um repositório com um docker-compose.yml ou usar a opção de “Custom Container”. Abaixo está um exemplo minimalista (adaptado) para servir como base, ajuste conforme sua rede e volumes e substitua “YOUR_DOMAIN” pelo seu domínio (ex: cienciaembarcada.com.br):
services:
stalwart-mail:
image: 'stalwartlabs/stalwart:latest'
container_name: stalwart-mail
hostname: mail.YOUR_DOMAIN
networks:
- coolify
ports:
- '25:25'
- '587:587'
- '465:465'
- '143:143'
- '993:993'
- '4190:4190'
- '110:110'
- '995:995'
volumes:
- 'stalwart-data:/opt/stalwart'
- '/etc/localtime:/etc/localtime:ro'
- '/data/coolify/certs:/data/certs:ro'
tty: true
stdin_open: true
restart: always
labels:
- traefik.enable=true
- 'traefik.http.routers.mailserver.rule=Host(`mail.YOUR_DOMAIN`) || Host(`autodiscover.YOUR_DOMAIN`) || Host(`autoconfig.YOUR_DOMAIN`)'
- traefik.http.routers.mailserver.entrypoints=https
- traefik.http.routers.mailserver.service=mailserver
- traefik.http.services.mailserver.loadbalancer.server.port=8080
- 'traefik.tcp.routers.smtp.rule=HostSNI(`*`)'
- traefik.tcp.routers.smtp.entrypoints=smtp
- traefik.tcp.routers.smtp.service=smtp
- traefik.tcp.services.smtp.loadbalancer.server.port=25
- traefik.tcp.services.smtp.loadbalancer.proxyProtocol.version=2
- 'traefik.tcp.routers.jmap.rule=HostSNI(`*`)'
- traefik.tcp.routers.jmap.tls.passthrough=true
- traefik.tcp.routers.jmap.entrypoints=https
- traefik.tcp.routers.jmap.service=jmap
- traefik.tcp.services.jmap.loadbalancer.server.port=443
- traefik.tcp.services.jmap.loadbalancer.proxyProtocol.version=2
- 'traefik.tcp.routers.smtps.rule=HostSNI(`*`)'
- traefik.tcp.routers.smtps.tls.passthrough=true
- traefik.tcp.routers.smtps.entrypoints=smtps
- traefik.tcp.routers.smtps.service=smtps
- traefik.tcp.services.smtps.loadbalancer.server.port=465
- traefik.tcp.services.smtps.loadbalancer.proxyProtocol.version=2
- 'traefik.tcp.routers.imaps.rule=HostSNI(`*`)'
- traefik.tcp.routers.imaps.tls.passthrough=true
- traefik.tcp.routers.imaps.entrypoints=imaps
- traefik.tcp.routers.imaps.service=imaps
- traefik.tcp.services.imaps.loadbalancer.server.port=993
- traefik.tcp.services.imaps.loadbalancer.proxyProtocol.version=2
volumes:
stalwart-data: null
networks:
coolify:
external: trueNo painel do Coolify:
- Crie um novo app do tipo Docker Compose Empty (ou Custom).
- Faça o deploy do compose acima (ou do que você preparou).
- Habilite a opção Connect To Predefined Network.
- Crie um link para o serviço Stalwart sendo: https://mail.YOUR_DOMAIN:8080
- Faça o deploy do Stalwart.
⚠️
É muito importante que o link do serviço do Stalwart seja “https://mail.YOUR_DOMAIN:8080”, no meu caso, “https://mail.cienciaembarcada.com.br:8080”
⚠️
Assim que você fizer o deploy, copie a senha que vai aparecer nos logs do container e armazene em lugar seguro, ela é a senha do usuário admin do seu Stalwart.
Configurando o Stalwart
Agora você precisa editar o arquivo config.toml do Stalwart. e para isso você vai precisar utilizar os seguintes comandos no terminal SSH do seu servidor:
# Ver todos os containers docker em execução docker ps # Ver qual é o caminho do volume do Starwart (campo Source) docker inspect CONTAINER_NAME | grep -A 5 volume # Editar o config.toml # nano VOLUME_SOURCE/etc/config.toml
É muito importante que o arquivo esteja parecido com o seguinte:
[server]
hostname = "mail.YOUR_DOMAIN"
[certificate."default"]
cert = "%{file:/data/certs/mail.YOUR_DOMAIN/cert.pem}%"
private-key = "%{file:/data/certs/mail.YOUR_DOMAIN/key.pem}%"
[server.listener.smtp]
bind = "[::]:25"
protocol = "smtp"
tls.implicit = false
[server.listener.submission]
bind = "[::]:587"
protocol = "smtp"
tls.implicit = false
[server.listener.submissions]
bind = "[::]:465"
protocol = "smtp"
tls.implicit = true
[server.listener.imap]
bind = "[::]:143"
protocol = "imap"
[server.listener.imaptls]
bind = "[::]:993"
protocol = "imap"
tls.implicit = true
[server.listener.pop3]
bind = "[::]:110"
protocol = "pop3"
[server.listener.pop3s]'
bind = "[::]:995"
protocol = "pop3"
tls.implicit = true
[server.listener.sieve]
bind = "[::]:4190"
protocol = "managesieve"
[server.listener.http]
protocol = "http"
bind = "[::]:8080"
[storage]
data = "rocksdb"
fts = "rocksdb"
blob = "rocksdb"
lookup = "rocksdb"
directory = "internal"
[store.rocksdb]
type = "rocksdb"
path = "/opt/stalwart/data"
compression = "lz4"
[directory.internal]
type = "internal"
store = "rocksdb"
[tracer.log]
type = "log"
level = "info"
path = "/opt/stalwart/logs"
prefix = "stalwart.log"
rotate = "daily"
ansi = false
enable = true
[authentication.fallback-admin]
user = "admin"
secret = "HASH_SHA_512_OF_ADMIN_PASSWORD"💡
Você pode criar o hash de uma nova senha utilizando o comando:
openssl passwd -6 “new-password”
Após editar o config.toml, basta você reiniciar o container do stalwart, e para isso você pode utilizar o painel do Coolify ou o seguinte comando:
docker restart CONTAINER_NAME
Configurando o Domínio
Acesse o link do Stalwart (https://mail.YOUR_DOMAIN), no meu caso:
https://mail.cienciaembarcada.com.br
Faça o login utilizando o usuário “admin” e senha que apareceu no terminal quando você fez o primeiro deploy. Dentro do painel do Stalwart, acesse a página Directory -> Domains.

Dentro dessa página, clique no botão de criar um novo domínio.

Depois é só preencher como o nome do seu domínio (no meu caso é “cienciaembarcada.com.br”) e salvar.

Em seguida, clique nos 3 pontinhos e vá na opção “View DNS records”.

Agora você vai ver todos os registros DNS que você precisa configurar, mas se você seguiu todos os passos anteriores, só faltaram alguns, e os principais deles são os que eu demarquei em roxo na imagem abaixo:

Depois de configurar isso no seu provedor DNS, basta ir na página de usuários em Directory -> Accounts para criar as contas de e-mail que você precisar.

Agora é só clicar no botão de criar uma nova conta.

Agora você pode configurar um e-mail, idioma para um usuário, mas é muito importante que o Login name seja igual ao Email.

Agora você só precisa ir na aba Authentication, configurar uma senha para o usuário e salvar ele.

Por fim, precisamos aumentar os limites de conexão, pois os padrões são muito baixos e acabam bloqueando alguns testes, como o do top.nic.br. Para isso, vá na opção Settings.

Na página de configurações, acesse a opção SMTP -> Inbound -> Rate Limits.

Agora você pode configurar limites para valores iguais ou maiores aos que eu coloquei. Você também pode colocar limites menores, mas eu tive problemas com isso.

Agora você só precisa ajustar as políticas de MTA-STS em SMTP -> Inbound -> MTA-STS.

Edite as políticas do MTA-STS para ficar igual ao arquivo criado anteriormente.

Parabéns! Agora você tem um servidor de e-mails funcional e seguindo boas práticas de segurança.
Hardening e boas práticas de segurança
Durante meus testes, aplicar regras simples aumentou muito a segurança e a pontuação em verificadores:
- Firewall: permita apenas portas necessárias (25, 587, 465, 993 se aplicável, 443 para web). Bloqueie o painel do Coolify por IP quando possível.
- Fail2ban / proteção contra força bruta: use sistemas que bloqueiem tentativas excessivas de autenticação.
- Isolamento de volumes: garanta permissões adequadas e backups regulares das chaves e do banco de dados do mail.
- Atualizações: mantenha a imagem do Stalwart atualizada e aplique atualizações do host.
- Limites e quotas: defina limites de envio para evitar abuso e manter reputação.
Como testar e validar (incluindo top.nic.br)
Depois do deploy e configuração DNS, execute estes passos de validação:
- Verifique os registros DNS com
digou ferramentas online. - Envie e-mails de teste e verifique cabeçalhos para assinatura DKIM, SPF e alinhamento DMARC.
- Use validadores como top.nic.br para checar melhores práticas e entrega.
- Testes adicionais: MXToolbox, mail-tester.com.
Monitoramento e manutenção
Eu costumo automatizar backups do volume de configuração e das chaves DKIM. Além disso, monitoro logs do serviço e alertas de taxa de rejeição para detectar problemas de reputação. Integre com ferramentas de logging do Coolify ou envie logs para um ELK/Prometheus se precisar de histórico e métricas.
Conclusão
Configurar Stalwart no Coolify é uma ótima forma de ter um servidor de e-mail moderno sem perder o controle. Seguindo as etapas de DNS, TLS, assinatura DKIM e políticas DMARC, além das práticas de hardening, você aumenta significativamente as chances de entrega e a segurança do serviço. Durante meus testes, essas práticas me ajudaram a alcançar nota máxima no top.nic.br.
Veja mais sobre o top.nic.br nesse post.
Links úteis: Stalwart Security Docs | Coolify Docs | top.nic.br


Deixe um comentário