Fonte: O Autor (gerada por IA).

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.

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:

RegistroNomeDados
Amail.YOUR_DOMAINEndereço IPv4 público do seu servidor.
AAAAmail.YOUR_DOMAINEndereço IPv6 do seu servidor.
MXYOUR_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”
CNAMEautoconfig.YOUR_DOMAINmail.cienciaembarcada.com.br
CNAMEautodiscover.YOUR_DOMAINmail.cienciaembarcada.com.br
CNAMEmta-sts.YOUR_DOMAINEndereç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=80

Perceba 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: true

No painel do Coolify:

  1. Crie um novo app do tipo Docker Compose Empty (ou Custom).
  2. Faça o deploy do compose acima (ou do que você preparou).
  3. Habilite a opção Connect To Predefined Network.
  4. Crie um link para o serviço Stalwart sendo: https://mail.YOUR_DOMAIN:8080
  5. Faça o deploy do 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"

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.

Fonte: O Autor.

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

Fonte: O Autor.

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

Fonte: O Autor.

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

Fonte: O Autor.

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:

Fonte: O Autor.

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.

Fonte: O Autor.

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

Fonte: O Autor.

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

Fonte: O Autor.

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

Fonte: O Autor.

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.

Fonte: O Autor.

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

Fonte: O Autor.

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.

Fonte: O Autor.

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

Fonte: O Autor.

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

Fonte: O Autor.

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:

  1. Verifique os registros DNS com dig ou ferramentas online.
  2. Envie e-mails de teste e verifique cabeçalhos para assinatura DKIM, SPF e alinhamento DMARC.
  3. Use validadores como top.nic.br para checar melhores práticas e entrega.
  4. 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

Para citar esse artigo:

GUERRA DA SILVA, L. R. Como configurar o Stalwart no Coolify com segurança. Ciência Embarcada. Recife. 14 fev. 2026. Disponível em: https://cienciaembarcada.com.br/publicacoes/configurar-stalwart-coolify-seguranca/. Acesso em: 14 fev. 2026.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Lucas Guerra

Autista e entusiasta do mundo da tecnologia. Criei esse blog para poder compartilhar conhecimentos e experiências de forma acessível, traduzindo esse infinidades de termos da tecnologia. Eu trabalho com o desenvolvimento de dispositivos IoT e Sistemas Web, indo do desenho de PCBs até a interface com o usuário, e sempre com foco em segurança e inovação.