SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

Mailcow na VPS: como o Gmail aceita seus emails

Teste a porta 25 antes de instalar o mailcow: bloqueio deixa mensagens na fila até o bounce. Configure DNS e evite o erro 550 5.7.25 do Gmail por PTR.

O que você vai criar

Um servidor de email completo num servidor que controla: SMTP para enviar e receber, IMAP para manter o telefone e o portátil sincronizados, um cliente de webmail e um filtro de spam que atribui uma pontuação a cada mensagem nas duas direções. O mailcow-dockerized reúne Postfix, Dovecot, Rspamd, webmail SOGo, MariaDB, Redis e um cliente ACME numa única stack do Docker Compose, por isso o software não é a parte difícil. Terá tudo a funcionar em meia hora.

A parte difícil está em tudo o que o rodeia. O email é o único serviço em que o resto da Internet desconfia ativamente de um servidor novo, e a diferença entre “funciona” e “o Gmail elimina silenciosamente todas as mensagens” depende sobretudo de quatro registos DNS e de uma definição de reputação do IP que pode não controlar totalmente. Leia os pré-requisitos abaixo antes de arrendar qualquer servidor. Se, depois de os ler, decidir que o esforço necessário para criar reputação não compensa, essa é uma conclusão legítima. a nossa análise do que vale realmente a pena alojar autonomamente em 2026 classifica o email como “só se levar isso a sério” precisamente por estas razões.

Os pré-requisitos SÃO o projeto

Se faltar algum deles, você enviará mensagens que nunca chegarão. A ordem abaixo é aproximada, das causas mais frequentes de falha para as menos frequentes:

A porta de saída 25 deve estar aberta. O seu servidor entrega mensagens ao Gmail e à Microsoft pela porta TCP 25. Muitos provedores de VPS e cloud bloqueiam a porta 25 de saída por padrão para combater spam. Esse bloqueio é silencioso: nada falha no boot, tudo parece funcionar e as mensagens ficam adiadas na fila até o Postfix desistir e devolvê-las. O mailcow define o tempo máximo de permanência na fila como cinco dias. Teste isso antes de instalar qualquer componente. Se a porta estiver bloqueada, a única solução é abrir um chamado ao provedor e pedir a liberação. Alguns provedores fazem isso para contas antigas; outros nunca liberam.

Um IP limpo, com reputação utilizável. IPs reciclados de VPS muitas vezes já estão em blocklists por causa de spam enviado pelo inquilino anterior. Consulte o seu IP em um serviço como a consulta do Spamhaus ou o mxtoolbox antes de prosseguir. Um IP listado causa rejeições que não podem ser resolvidas com alterações de código.

Controle do DNS e um registro PTR correto. Você precisa adicionar registros à zona do seu domínio e configurar o DNS reverso (PTR) do IP do servidor para apontar de volta para o hostname de e-mail. O PTR quase nunca é configurado no seu painel de DNS. Ele fica sob responsabilidade de quem possui o IP, portanto é configurado no painel de controle do provedor de VPS ou por meio de um chamado.

6 GiB de RAM e 2 vCPU são o mínimo confortável. O requisito mínimo indicado pelo próprio mailcow é 6 GiB de RAM mais 1 GiB de swap para uma instalação privada. São recomendados 8 GiB quando alguns utilizadores já dependem do serviço. Abaixo de aproximadamente 2.5 GiB, o generate_config.sh oferece desativar o antivírus ClamAV para impedir que o kernel comece a encerrar containers. O mínimo de disco documentado pelo mailcow é 20 GiB antes de armazenar qualquer mensagem. Portanto, comece com mais espaço e deixe margem para o crescimento das caixas de correio.

Um nome DNS, não um IP isolado. Escolha um hostname como mail.example.com. Esse único nome será o seu MAILCOW_HOSTNAME, o assunto do seu certificado TLS, o destino do seu PTR e o banner SMTP. Mantenha o nome consistente em todos os locais.

Passo 1: confirme que a porta de saída 25 está aberta

Faça isto primeiro. Todo o restante será esforço perdido se falhar. A partir do VPS novo, tente iniciar uma conversa SMTP com um servidor de correio real:

sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 gmail-smtp-in.l.google.com 25

Quando funciona, o resultado é imediato:

Connection to gmail-smtp-in.l.google.com (142.250.x.x) 25 port [tcp/smtp] succeeded!

Quando a porta está bloqueada, o comando aguarda os cinco segundos completos e depois falha:

nc: connect to gmail-smtp-in.l.google.com port 25 (tcp) timed out: Operation now in progress

Num VPS novo, sem regras de firewall de saída configuradas por si, esse timeout é causado pelo bloqueio do fornecedor. Trata-se de um filtro de rede do lado do fornecedor, não do seu firewall. Nenhuma alteração local o resolve. Abra um ticket com a mensagem: "Please enable outbound TCP port 25 for my VPS at <IP>; I am running a legitimate mail server." Não instale o mailcow enquanto este comando não devolver "succeeded". Tenha em atenção que a porta 25 de entrada, usada por outros servidores para estabelecer ligações consigo, é um caminho separado e normalmente está aberta. É o tráfego de saída que os fornecedores limitam.

Etapa 2, configure já os registos DNS

As alterações DNS demoram a propagar-se, por isso publique tudo o que puder antes da instalação. Considere que o seu domínio é example.com, o seu servidor de correio é mail.example.com e o IP é 10.0.0.10. Na sua zona, crie:

mail.example.com.        A      10.0.0.10
mail.example.com.        AAAA   2001:db8::10          ; only if you have IPv6
example.com.             MX  10 mail.example.com.
example.com.             TXT    "v=spf1 mx -all"
_dmarc.example.com.      TXT    "v=DMARC1; p=none; rua=mailto:postmaster@example.com"

O registo SPF indica que «apenas o meu MX pode enviar por este domínio; rejeite os restantes». Comece o DMARC com p=none para poder monitorizar os relatórios sem rejeitar as suas próprias mensagens. Depois de confirmar o alinhamento, altere para p=quarantine e, em seguida, para p=reject. Faltam ainda dois registos de propósito: DKIM, que o mailcow gera por si na Etapa 6, e PTR, que deve configurar agora no painel do seu fornecedor.

Configure o PTR (DNS inverso) de 10.0.0.10 para mail.example.com, o valor exato de MAILCOW_HOSTNAME. Este é o único registo que a maioria das pessoas esquece, e os grandes fornecedores rejeitam mensagens com base nele. Se o seu painel não tiver um campo de rDNS, abra um ticket.

Passo 3, instalar o Docker

O mailcow requer o Docker Engine 24.0 ou mais recente e o Docker Compose 2.0 ou mais recente. O plug-in Compose (docker compose) é a opção mais simples, embora o mailcow também suporte o binário autónomo docker-compose. Use o script oficial de conveniência do Docker em vez do pacote docker.io do Ubuntu, que não inclui qualquer plug-in Compose:

curl -fsSL https://get.docker.com | sudo sh
sudo docker compose version

Deverá ver uma linha Docker Compose version a indicar v2.x ou v5.x. O Compose v5, lançado em 2025, é funcionalmente idêntico ao v2, e qualquer um dos dois satisfaz os requisitos do mailcow. Se docker compose version mostrar docker: 'compose' is not a docker command, o Docker Engine está instalado, mas o plug-in Compose não está. Instale o plug-in a partir do repositório do Docker, execute novamente o script acima ou consulte o nosso guia básico do Docker Compose, que configura ambos a partir do próprio repositório apt do Docker.

Etapa 4, Clone o mailcow e gere a configuração

cd /opt
sudo git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
umask
sudo ./generate_config.sh

Confirmar que umask imprime 0022 segue as próprias etapas de instalação do mailcow, que definem umask 0022 antes da clonagem. O mailcow não testa esse valor, e uma shell root nova no Ubuntu 24.04 já fornece 0022. Em seguida, o script pede o único dado que importa: o hostname totalmente qualificado. Introduza mail.example.com. O valor tem de corresponder exatamente ao seu registo A e ao PTR. O script grava mailcow.conf, o único ficheiro de ambiente lido por toda a stack. Abra-o se precisar de alterar as portas web (HTTP_PORT, HTTPS_PORT) ou desativar o ClamAV num servidor pequeno:

MAILCOW_HOSTNAME=mail.example.com
HTTP_PORT=80
HTTPS_PORT=443
SKIP_CLAMD=n          # set to y to drop the virus scanner on a <2.5 GiB box

SKIP_FTS=y é o outro parâmetro relevante num servidor com pouca RAM: a pesquisa de texto completo é o segundo maior consumidor de memória indicado na documentação do mailcow, e ignorá-la apenas elimina a pesquisa pelo corpo das mensagens no webmail.

Mantenha HTTP_PORT=80 e HTTPS_PORT=443, exceto se outro serviço no host já os utilizar. O cliente ACME integrado do mailcow usa o desafio HTTP-01 por predefinição, que precisa da porta 80 acessível a partir da Internet para obter o certificado. (O mailcow 2026-03 e versões posteriores também podem usar um desafio DNS-01 com ACME_DNS_CHALLENGE=y. Esse método não precisa da porta 80, mas precisa de acesso à API do seu fornecedor de DNS.) Por isso, o layout simples não executa uma configuração separada de nginx e Certbot no mesmo servidor. O mailcow emite e renova internamente os seus próprios certificados TLS, e um segundo serviço a ocupar as portas 80/443 interrompe esse funcionamento. O mailcow documenta a alternativa: vincule os seus listeners web localmente com HTTP_BIND=127.0.0.1 HTTP_PORT=8080 HTTPS_BIND=127.0.0.1 HTTPS_PORT=8443, coloque um reverse proxy nas portas 80 e 443 e, se quiser que um Certbot local seja responsável pelos certificados, indique esses certificados ao mailcow e adicione um hook de renovação. Isto acrescenta mais componentes a um servidor de email. A mesma decisão aplica-se a qualquer outro serviço que queira uma interface web pública: uma configuração como o Halcyon transformar uma biblioteca Jellyfin numa loja de vídeo dos anos 90, que espera o seu próprio reverse proxy na porta 443, deve ficar noutro host, a menos que coloque o mailcow atrás desse proxy. A exceção é um serviço que nunca peça uma porta web pública: um relay RustDesk self-hosted escuta apenas no seu próprio intervalo de 21115 a 21119, pelo que pode partilhar o servidor, desde que exista largura de banda disponível suficiente.

Etapa 5, Inicie a stack e inicie sessão

sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps

O pull obtém aproximadamente duas dezenas de imagens; aguarde alguns minutos. Quando docker compose ps mostrar todos os contentores como running (ou healthy), abra https://mail.example.com/admin num browser. O início de sessão predefinido do administrador usa o nome de utilizador admin e a palavra-passe moohoo. Altere essa palavra-passe imediatamente na interface de administração, em System → Configuration e depois em Access → Administrators. Se o browser mostrar o aviso NET::ERR_CERT_AUTHORITY_INVALID, o certificado ACME ainda não foi emitido. Consulte a falha ACME abaixo antes de concluir que existe um problema; é normal existir um certificado temporário autoassinado durante o primeiro ou os primeiros dois minutos.

Etapa 6, Adicione um domínio, uma mailbox e publique o DKIM

Na interface de administração, abra E-Mail → Configuration e, no separador Domains, clique em Add domain e introduza example.com. Depois, em Mailboxes, clique em Add mailbox para criar you@example.com com uma palavra-passe. Essa mailbox já fica acessível por IMAP.

Agora, a chave DKIM. Aceda a System → Configuration e depois a Options → ARC/DKIM keys. O mailcow pode já ter gerado uma chave quando adicionou o domínio. Caso contrário, gere-a nessa página, selecione o domínio, mantenha o seletor dkim, escolha 2048-bit e clique em Add. Copie o valor TXT longo apresentado e publique-o como:

dkim._domainkey.example.com.  TXT  "v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqh...long-key...QAB"

A página Domains do mailcow tem um botão DNS que lista todos os registos esperados e mostra uma marca verde ou uma cruz vermelha conforme o que está efetivamente publicado. Use-a como lista de verificação e obtenha uma indicação verde em todas as linhas antes de testar a entrega de mensagens. Uma linha DKIM vermelha depois da publicação normalmente significa que a chave foi dividida incorretamente entre vários blocos TXT. Uma chave de 2048-bit é maior do que o limite de 255 caracteres de uma única string TXT. Cole-a como um único valor lógico e deixe o seu fornecedor de DNS dividi-la em blocos.

Etapa 7, testar a entregabilidade e chegar a 10/10

Aceda a mail-tester.com, copie o endereço aleatório apresentado e envie-lhe uma mensagem a partir da sua nova caixa de correio. Inicie sessão no webmail SOGo em https://mail.example.com/SOGo e envie a mensagem a partir daí. Depois, clique em "Then check your score".

Procure obter 10/10. Estas são as deduções mais comuns e as respetivas causas:

  • SPF não alinhado, o registo MX/SPF está em falta ou não inclui o IP de envio. Verifique novamente o TXT do SPF.
  • A assinatura DKIM não é validada, o TXT dkim._domainkey está em falta, ainda está a propagar-se ou foi alterado. Esta é a falha mais comum.
  • Sem PTR / PTR incompatível, o DNS inverso não resolve para mail.example.com. Corrija o problema junto do fornecedor.
  • Listado numa blocklist, devido ao histórico de reputação do seu IP. Peça a remoção da listagem ou solicite um IP com melhor reputação.

Não envie mensagens reais para o Gmail ou o Outlook até o resultado ser 10/10. Uma pontuação baixa combinada com um IP novo pode fazer com que o seu domínio seja sinalizado logo no primeiro dia.

Passo 8, Conecte um cliente de email real

Configure o Thunderbird, o Apple Mail ou o telemóvel com estas definições. O servidor é mail.example.com em todos os casos:

  • IMAP: porta 993, SSL/TLS (ou 143 com STARTTLS)
  • Envio SMTP: porta 465, SSL/TLS (ou 587 com STARTTLS)
  • Nome de utilizador: o endereço completo, you@example.com
  • Palavra-passe: a palavra-passe da caixa de correio que definiu

Nunca envie mensagens do cliente pela porta 25. Essa porta destina-se apenas à comunicação entre servidores. O mailcow não disponibiliza envio autenticado nessa porta, e as ligações de clientes direcionadas para ela são recusadas. Se um cliente indicar Relay access denied, está a tentar enviar pela porta 25 ou sem autenticação. Altere a configuração para a porta 465 ou 587 e use as credenciais da sua caixa de correio.

Passo 9, Faça backup do que realmente importa

O mailcow inclui um script de backup que cria snapshots de todos os volumes com estado. Execute-o num disco externo ou num recurso remoto montado:

sudo MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups \
  ./helper-scripts/backup_and_restore.sh backup all

all captura seis elementos, e perder qualquer um deles causa perda de dados: vmail (as caixas de correio propriamente ditas), crypt (as chaves que desencriptam o vmail, que não serve para nada sem elas), mysql (o MariaDB que armazena os domínios, utilizadores, aliases e definições), redis (o estado das filas e da cache), rspamd (a aprendizagem de spam e ham) e postfix (a fila de correio). O script é executado dentro de um contentor auxiliar que grava arquivos comprimidos, por isso os backups permanecem consistentes mesmo enquanto a stack está em execução. Automatize-o com um cron job noturno e adicione --delete-days 14 para eliminar conjuntos antigos. Um cron job que deixa de funcionar falha silenciosamente, por isso envie o estado de saída do script para um local que irá efetivamente verificar; um servidor ntfy autoalojado aceita um comando curl numa única linha da mesma entrada do cron e envia a falha para o seu telefone na noite em que ocorre. A restauração usa o mesmo script com restore, que lista os snapshots e permite escolher o que pretende restaurar. Um backup que nunca foi testado através de uma restauração é uma esperança, não um backup; faça um teste sem efeitos num VPS temporário.

Passo 10, Atualize segundo um agendamento

O mailcow é atualizado pelo próprio script, que obtém o código novo, migra mailcow.conf, pré-obtém as imagens e reinicia os contentores pela ordem correta:

cd /opt/mailcow-dockerized
sudo ./update.sh --check   # reports whether an update exists, changes nothing
sudo ./update.sh           # applies it

Faça primeiro a cópia de segurança (Passo 9), porque é difícil reverter uma migração de esquema. As atualizações são disponibilizadas com frequência e incluem correções de segurança para daemons expostos à Internet. Não deixe um servidor de correio sem atualizações durante meses. Se uma atualização deixar um contentor não íntegro, sudo docker compose logs --tail=50 <service>-mailcow identifica o daemon que não voltou a iniciar.

Uma nota sobre hardening

O mailcow executa o seu próprio serviço netfilter (netfilter-mailcow), que bloqueia endereços IP que fazem muitas tentativas contra as portas de mail e webmail. Por isso, a componente de mail fica protegida por defeito. Isto não protege o SSH no próprio host, que continua exposto e sujeito a ataques de força bruta. Combine esta configuração com Fail2ban a monitorizar o log de autenticação do SSH e permita apenas autenticação por chave. Proteja a interface de administração do mailcow com uma palavra-passe forte e, idealmente, retire-a da Internet pública ou disponibilize-a apenas através de uma VPN.

Modos de falha, com as strings exatas

As filas de correio acumulam mensagens e estas nunca são entregues. Execute sudo docker compose exec postfix-mailcow postqueue -p ou consulte a fila de correio na interface de administração. As entradas ficam adiadas durante até cinco dias, antes de o Postfix as devolver, com:

status=deferred (connect to gmail-smtp-in.l.google.com[142.250.x.x]:25: Connection timed out)

Isto é quase sempre causado pelo bloqueio da porta de saída 25 pelo seu fornecedor (Passo 1). Uma regra de saída na firewall do próprio host produz o mesmo timeout, por isso exclua primeiro essa possibilidade. Se o host estiver correto, nenhuma alteração de configuração resolverá o problema; abra um ticket. Não é um problema de DNS nem de TLS. O indício é a palavra timed out associada a um MX remoto na porta 25.

O Gmail marca todas as mensagens como spam ou devolve-as. Abra a mensagem no Gmail, selecione "Show original" e consulte os resultados da autenticação. dkim=fail ou dkim=none significa que o seu registo TXT dkim._domainkey está em falta, incorreto ou ainda não foi propagado. Publique novamente exatamente o que a página ARC/DKIM mostra e aguarde o TTL. spf=fail significa que os registos SPF/MX não incluem o seu IP. O alinhamento é essencial. Uma verificação falhada é suficiente para colocar a mensagem em spam.

Os grandes fornecedores rejeitam a ligação. As devoluções ou os logs do Postfix contêm a rejeição de PTR do Gmail:

550-5.7.25 [10.0.0.10] The IP address sending this message does not have a PTR
550-5.7.25 record setup, or the corresponding forward DNS entry does not match
550 5.7.25 the sending IP. As a policy, Gmail does not accept messages from IPs
550 5.7.25 with missing PTR records.

O código 550 5.7.25 significa que o reverse DNS está em falta ou não corresponde. Defina o PTR do seu IP como mail.example.com no fornecedor (Passo 2). O DNS direto (A) e o inverso (PTR) têm de corresponder, e ambos têm de indicar o mesmo host com que o mailcow se identifica perante os outros servidores.

O browser mostra um aviso de certificado que nunca desaparece. O contentor acme-mailcow não conseguiu obter um certificado válido. Consulte o respetivo log:

sudo docker compose logs acme-mailcow | tail -n 40

Uma linha como Cannot validate any hostnames, skipping Let's Encrypt for 1 hour. ou uma falha no challenge significa que a porta 80 não está acessível a partir da Internet ou que o registo A não aponta para este servidor. Se publicou um registo AAAA, verifique-o também: o mailcow valida primeiro o registo AAAA e ignora a verificação do A quando este existe. Portanto, um AAAA incorreto ou um caminho IPv6 que não consiga alcançar a porta 80 faz a validação falhar, mesmo com um registo A correto. Confirme que mail.example.com resolve para este host, permita as portas 80 e 443 em qualquer firewall do host e garanta que mais nenhum processo está a escutar nessas portas. Depois de corrigir a causa, reinicie o cliente com sudo docker compose restart acme-mailcow, em vez de aguardar o back-off de uma hora.

FAQ

O self-hosting de email vale mesmo a pena?

Se pretende controlo dos dados, aliases ilimitados e controlo total, sim: o mailcow oferece uma stack profissional pelo preço de um VPS. Mas a entregabilidade exige manutenção contínua: a reputação do IP, o alinhamento do DNS e a monitorização de blocklists nunca ficam totalmente resolvidos. Para um endereço empresarial crítico, em que um único dia na pasta de spam de alguém lhe causa prejuízos, um fornecedor gerido é a escolha pragmática. Faça self-hosting quando valoriza o controlo mais do que a conveniência e estiver disposto a mantê-lo. Se o que pretende realmente é tirar os dados dos servidores de terceiros, e não necessariamente alojar email, comece por um serviço sobre o qual mais ninguém possa decidir: uma biblioteca de fotografias não tem qualquer problema de entregabilidade, e a nossa comparação entre PhotoPrism e Immich cobre os requisitos mínimos de RAM e os comandos de backup para essa implementação no mesmo tipo de VPS.

Como sei se a porta de saída 25 está bloqueada?

Execute nc -vz -w 5 gmail-smtp-in.l.google.com 25 no servidor. A mensagem "succeeded!" significa que está aberta; um timed out depois da pausa significa que a porta está bloqueada e, num servidor sem regras próprias de firewall de saída, o bloqueio é do fornecedor. Esta é a razão mais comum para um servidor self-hosted conseguir receber email, mas nunca o conseguir enviar. A única correção para um bloqueio do fornecedor é o próprio fornecedor abrir a porta; nenhuma alteração local a desbloqueia.

Porque é que o meu email continua a chegar à pasta de spam do Gmail?

Quase sempre devido a uma cadeia de autenticação inválida. Use "Show original" no Gmail e procure spf=pass, dkim=pass e dmarc=pass. Um dkim=fail indica um registo TXT dkim._domainkey em falta ou incorreto. Uma divergência no PTR ou um IP novo sem histórico de envio também prejudicam a entregabilidade. Primeiro, obtenha 10/10 no mail-tester.com. Depois, aqueça o IP lentamente, começando com algumas mensagens por dia e aumentando gradualmente, em vez de enviar um grande volume logo no primeiro dia.

Do que preciso exatamente de fazer backup?

Execute backup_and_restore.sh backup all e mantenha todo o conjunto fora do servidor. O comando inclui vmail (as caixas de correio), crypt (as chaves que as desencriptam), a base de dados MariaDB (domínios, utilizadores, aliases e definições), Redis, os dados aprendidos pelo Rspamd e a fila do Postfix. O volume crypt é frequentemente ignorado. Sem ele, o backup de vmail é composto por texto cifrado ilegível. Teste uma restauração num servidor de teste pelo menos uma vez.

Posso executar o mailcow num VPS com 2 GB de RAM?

Não de forma confortável. generate_config.sh propõe desativar o ClamAV abaixo de cerca de 2.5 GiB. Mesmo com o ClamAV desativado, o Rspamd, o Dovecot, o MariaDB e o restante da stack competem pela memória. Sob qualquer carga real, irá utilizar swap e sofrer terminações por OOM. Considere 6 GiB mais 1 GiB de swap como o mínimo para uma instalação estável com um único utilizador. Passe para 8 GiB assim que mais de duas pessoas dependerem do serviço.