Mailcow em VPS: email próprio que o Gmail aceita
Teste a porta 25 antes de instalar o mailcow: se estiver bloqueada, o email fica na fila. Configure o DNS correto para evitar o erro 550 5.7.25 do Gmail.
O que você vai criar
Um servidor de correio completo num servidor que você 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 todas as mensagens, nos dois sentidos. 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 mais difícil. O servidor ficará a funcionar em meia hora.
A parte difícil é tudo o que o rodeia. O email é o único serviço em que o resto da Internet desconfia ativamente de um servidor novo. A diferença entre "funciona" e "o Gmail elimina silenciosamente todas as mensagens" resume-se a quatro registos DNS e a uma configuração de reputação do IP que talvez você não consiga controlar totalmente. Leia os pré-requisitos abaixo antes de alugar qualquer servidor. Se, depois de os ler, decidir que o esforço necessário para criar uma reputação não compensa, essa é uma conclusão legítima. o nosso resumo do que realmente vale a pena alojar por conta própria em 2026 coloca o email na categoria "só se levar isto a sério" precisamente por estes motivos.
Os pré-requisitos SÃO o projeto
Se algum destes pontos falhar, irá enviar mensagens que nunca chegam ao destino. A ordem abaixo é aproximada, com base na frequência com que cada ponto causa problemas:
A porta de saída 25 deve estar aberta. O servidor entrega mensagens ao Gmail e à Microsoft através da porta TCP 25. Muitos fornecedores de VPS e cloud bloqueiam a porta 25 de saída por predefinição para combater spam. O bloqueio é silencioso: não há erros no arranque, tudo parece estar a funcionar e as mensagens ficam simplesmente na fila para sempre. Teste isto antes de instalar qualquer componente. Se a porta estiver bloqueada, a única solução é abrir um pedido de suporte para que o fornecedor a desbloqueie. Alguns fornecedores fazem isso para contas antigas; outros nunca o fazem.
Um IP limpo, com reputação utilizável. Os IPs reciclados de VPS já estão muitas vezes em blocklists devido a spam enviado pelo inquilino anterior. Verifique o seu num serviço como a consulta do Spamhaus ou o mxtoolbox antes de avançar. Um IP listado causa rejeições que não podem ser resolvidas através de código.
Controlo do DNS e um registo PTR correto. Precisa de adicionar registos à zona do seu domínio e de configurar o DNS inverso (PTR) do IP do servidor para apontar para o hostname de correio. O PTR quase nunca é configurado no painel de DNS. Fica sob a responsabilidade de quem controla o IP, pelo que é configurado no painel de controlo do fornecedor de VPS ou através de um pedido de suporte.
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 e 1 GiB de swap para uma instalação privada, sendo recomendados 8 GiB quando vários utilizadores dependem do serviço. Abaixo de cerca de 2.5 GiB, generate_config.sh propõe desativar o antivírus ClamAV para impedir que o kernel comece a terminar contentores. Reserve 20 GB de SSD para começar.
Um nome DNS, não apenas um IP. Escolha um hostname como mail.example.com. Esse nome único torna-se o seu MAILCOW_HOSTNAME, o sujeito do seu certificado TLS, o destino do seu PTR e o banner SMTP. Mantenha-o consistente em todos os locais.
Passo 1, confirme se a porta de saída 25 está aberta
Faça isto primeiro. Todo o restante será esforço desperdiçado se este passo falhar. A partir do VPS recém-criado, tente abrir uma sessão SMTP com um servidor de e-mail real:
sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 gmail-smtp-in.l.google.com 25Quando funciona, o resultado é imediato:
Connection to gmail-smtp-in.l.google.com (142.250.x.x) 25 port [tcp/smtp] succeeded!Uma porta bloqueada permanece pendente durante os cinco segundos completos e depois falha:
nc: connect to gmail-smtp-in.l.google.com port 25 (tcp) timed out: Operation now in progressEsse timeout indica o bloqueio. Trata-se de um filtro de rede aplicado pelo provedor, não pelo seu firewall, portanto nenhuma alteração local o corrige. Abra um ticket com a seguinte mensagem: "Please enable outbound TCP port 25 for my VPS at <IP>; I am running a legitimate mail server." Não instale o mailcow até este comando retornar "succeeded". A porta 25 de entrada, usada por outros servidores para se ligarem ao seu, segue um caminho separado e geralmente está aberta. É o tráfego de saída que os provedores 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.
Etapa 3, Instalar o Docker
O mailcow precisa do Docker Engine com o plugin Compose v2. Use o script oficial de instalação do Docker em vez do pacote docker.io do Ubuntu, que não inclui nenhum plugin Compose:
curl -fsSL https://get.docker.com | sudo sh
sudo docker compose versionDeverá ver uma linha Docker Compose version v2.x. Se docker compose version apresentar docker: 'compose' is not a docker command, o Docker Engine está instalado, mas o plugin Compose não está. Instale o plugin 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.
Passo 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.shConfirme que umask imprime 0022 primeiro. O mailcow recusa-se a compilar com uma máscara de ficheiros inadequada. Uma shell root nova no Ubuntu 24.04 já fornece 0022. O script pede então o único dado relevante: o hostname totalmente qualificado. Introduza mail.example.com. O valor tem de corresponder exatamente ao seu registo A e ao PTR. O script escreve 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 de desativar o ClamAV num servidor com poucos recursos:
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 boxSKIP_FTS=y é a outra opção relevante num servidor com pouca RAM. A pesquisa de texto completo é o segundo maior consumidor de memória indicado na documentação do mailcow. Desativá-la elimina apenas a pesquisa no corpo das mensagens no webmail.
Mantenha HTTP_PORT=80 e HTTPS_PORT=443, exceto se outro serviço no host já as utilizar. O cliente ACME integrado do mailcow precisa de ter a porta 80 acessível a partir da Internet para obter o certificado. Por isso, não execute uma configuração separada de nginx com 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 impede esse processo. O mesmo se aplica a qualquer outro serviço que precise de uma interface web pública. Por exemplo, uma configuração como o Halcyon a 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 exceção é um serviço que nunca peça uma porta web pública. Um relay RustDesk autoalojado escuta apenas no seu próprio intervalo de 21115 a 21119, pelo que pode partilhar o servidor, desde que exista largura de banda suficiente.
Etapa 5, iniciar a stack e iniciar sessão
sudo docker compose pull
sudo docker compose up -d
sudo docker compose psO comando pull obtém cerca de duas dezenas de imagens; aguarde alguns minutos. Quando docker compose ps mostrar todos os contentores como running (ou healthy), abra https://mail.example.com num navegador. As credenciais de administrador predefinidas são o nome de utilizador admin e a palavra-passe moohoo. Altere essa palavra-passe imediatamente na interface de administração, em Access → Administrators. Se o navegador emitir o aviso NET::ERR_CERT_AUTHORITY_INVALID, o certificado ACME ainda não foi emitido. Consulte a falha de ACME abaixo antes de concluir que existe um problema; é normal existir um certificado autoassinado temporário durante o primeiro ou os primeiros dois minutos.
Passo 6, adicionar um domínio, uma caixa de correio e publicar o DKIM
Na interface de administração, abra a página Mail Setup (Configuration → Mail Setup). No separador Domains, clique em Add domain e introduza example.com. Em seguida, em Mailboxes, clique em Add mailbox para criar you@example.com com uma palavra-passe. A caixa de correio já fica funcional e acessível por IMAP.
Agora, a chave DKIM. Aceda a Configuration → ARC/DKIM keys. O mailcow pode já ter gerado uma chave quando adicionou o domínio. Se isso não aconteceu, gere-a nessa página, selecione o domínio, mantenha o seletor dkim, escolha 2048-bit e clique em Add. Copie o valor TXT completo 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 apresenta todos os registos esperados e mostra uma marca verde ou uma cruz vermelha consoante o que está efetivamente publicado. Use-a como lista de verificação e confirme que todas as linhas ficam verdes antes de testar a capacidade de entrega. Uma linha DKIM vermelha depois da publicação normalmente significa que a chave foi dividida incorretamente entre vários fragmentos TXT. Uma chave de 2048-bit ultrapassa o limite de 255 caracteres de uma única cadeia TXT. Cole-a como um único valor lógico e deixe o seu fornecedor de DNS dividi-la em fragmentos.
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._domainkeyestá 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 allall 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 itFaç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 nunca entregam. Execute sudo docker compose exec postfix-mailcow postqueue -p ou consulte a fila de correio na interface de administração. As entradas permanecem adiadas com:
status=deferred (connect to gmail-smtp-in.l.google.com[142.250.x.x]:25: Connection timed out)Isto significa que a porta de saída 25 está bloqueada pelo seu fornecedor (Passo 1). Nenhuma alteração de configuração resolve o problema; abra um ticket. Não é um problema de DNS nem de TLS. O indicador é a palavra timed out associada a um MX remoto na porta 25.
O Gmail marca tudo como spam ou rejeita as mensagens. Abra a mensagem no Gmail, selecione "Mostrar original" e leia os resultados da autenticação. dkim=fail ou dkim=none significa que o TXT dkim._domainkey está em falta, foi alterado ou ainda não foi propagado. Publique novamente exatamente o conteúdo mostrado na página ARC/DKIM e aguarde o TTL. spf=fail significa que os registos SPF/MX não abrangem o seu IP. O alinhamento é essencial; uma única verificação com falha é suficiente para a mensagem acabar na pasta de spam.
Os grandes fornecedores rejeitam a ligação. As mensagens de devolução 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 DNS reverso está em falta ou não corresponde. Configure o PTR do seu IP como mail.example.com no fornecedor (Passo 2). O DNS direto (A) e o reverso (PTR) têm de corresponder, e ambos devem identificar o mesmo host com que o mailcow se apresenta aos outros servidores.
O navegador mostra um aviso de certificado que nunca desaparece. O contentor acme-mailcow não conseguiu obter um certificado válido. Verifique o log:
sudo docker compose logs acme-mailcow | tail -n 40Uma linha como Cannot validate any hostnames, skipping Let's Encrypt for 1 hour. ou uma falha no desafio 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. Confirme que mail.example.com resolve para este servidor, abra as portas 80 e 443 em qualquer firewall do host e certifique-se de que mais nenhum processo está associado a essas 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 alojamento próprio de email vale mesmo a pena?
Se pretende controlar os dados, ter aliases ilimitados e controlo total, sim: o mailcow oferece uma stack profissional pelo preço de um VPS. No entanto, a capacidade de entrega exige manutenção contínua: a reputação do IP, o alinhamento do DNS e a monitorização de blocklists nunca deixam de exigir atenção. Para um endereço empresarial crítico, em que um único dia na pasta de spam de alguém pode causar prejuízos, um fornecedor gerido é a opção pragmática. Aloje o email por conta própria se valoriza o controlo acima da conveniência e se está disposto a administrá-lo regularmente. Se o que realmente pretende é manter os seus dados fora dos servidores de terceiros, e não necessariamente alojar o email, comece por um serviço em que mais ninguém possa decidir: uma biblioteca de fotografias não tem qualquer problema de capacidade de entrega, 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 a porta está aberta; um timed out depois da pausa significa que o fornecedor a bloqueia. Esta é a razão mais comum para um servidor alojado por conta própria conseguir receber email, mas nunca o conseguir enviar. A única solução é o fornecedor abrir a porta; nenhuma alteração de configuração local resolve o problema.
Porque é que o meu email continua a cair na pasta de spam do Gmail?
Quase sempre por causa de uma cadeia de autenticação danificada. No Gmail, use "Show original" 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 entrega. 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 volume elevado 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 esquecido. Sem ele, o backup de vmail é texto cifrado ilegível. Teste uma restauração numa máquina de teste pelo menos uma vez.
Posso executar o mailcow num VPS com 2 GB?
Não de forma confortável. generate_config.sh propõe desativar o ClamAV abaixo de cerca de 2.5 GiB. Mesmo assim, Rspamd, ClamAV, Dovecot e MariaDB competem pela memória, pelo que haverá uso de swap e eliminações por OOM sob qualquer carga real. 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.