SSD Nodes Learn
Guide Matt ConnorDi Matt Connor · Aggiornato 2026-07-24

Installare mailcow su VPS per Gmail

Verifica la porta 25 prima di installare mailcow. Evita il rifiuto Gmail 550 5.7.25 PTR configurando correttamente i record DNS per l'invio sicuro.

Cosa stai costruendo

Un mail server completo su un server di tua proprietà: SMTP per inviare e ricevere, IMAP per sincronizzare smartphone e laptop, un client webmail e un filtro antispam che valuta ogni messaggio in entrambe le direzioni. mailcow-dockerized raggruppa Postfix, Dovecot, Rspamd, SOGo webmail, MariaDB, Redis e un client ACME in un unico stack Docker Compose; pertanto, il software non rappresenta la parte difficile. Il sistema sarà operativo in mezz'ora.

La parte difficile riguarda tutto ciò che lo circonda. L'email è l'unico servizio in cui il resto di internet diffida attivamente di un server nuovo di zecca. La differenza tra un sistema funzionante e un sistema in cui Gmail scarta silenziosamente ogni messaggio dipende da quattro record DNS e un'impostazione di IP-reputation che potresti non controllare completamente. Leggi i prerequisiti qui sotto prima di noleggiare qualsiasi servizio. Se, dopo averli letti, decidi che la gestione della reputation non ne valga la pena, è una scelta legittima — la nostra analisi su cosa valga davvero la pena auto-ospitare nel 2026 archivia le email sotto la sezione "solo se sei intenzionato" proprio per questi motivi.

I prerequisiti SONO il progetto

Se ne manca anche solo uno, le email non verranno consegnate. Ecco l'ordine approssimativo in base alla frequenza con cui causano problemi:

La porta outbound 25 deve essere aperta. Il server comunica con Gmail e Microsoft tramite la porta TCP 25. Molti provider di VPS e cloud bloccano la porta 25 in uscita per default per contrastare lo spam; il blocco è silenzioso: non compaiono errori all'avvio, il sistema risulta funzionante, ma le email rimangono bloccate nella coda per sempre. Effettua un test prima di procedere con l'installazione. Se la porta è bloccata, l'unica soluzione è aprire un ticket di supporto chiedendo al provider di sbloccarla; alcuni lo fanno per account storici, altri non lo faranno mai.

Un IP pulito con una reputazione valida. Gli IP riciclati dei VPS sono spesso già presenti in blocklist a causa dello spam inviato da precedenti utenti. Verifica il tuo IP tramite servizi come Spamhaus lookup o mxtoolbox prima di iniziare. Un IP in blocklist causa rifiuti che non possono essere risolti tramite configurazione software.

Controllo del DNS e record PTR corretto. È necessario aggiungere i record nella zona del dominio e configurare il DNS inverso (PTR) affinché l'IP del server punti al hostname della mail. Il record PTR non è quasi mai configurabile nel pannello DNS del dominio, poiché è gestito dal proprietario dell'IP; pertanto, va configurato nel pannello di controllo del provider VPS o tramite ticket.

6 GiB di RAM e 2 vCPU sono il limite minimo consigliato. Il requisito minimo di mailcow per un'installazione privata è 6 GiB di RAM più 1 GiB di swap; si consigliano 8 GiB quando il numero di utenti aumenta. Sotto i 2.5 GiB, generate_config.sh offre la possibilità di disabilitare il virus scanner ClamAV per evitare che il kernel interrompa i container. Assegna 20 GB di SSD per iniziare.

Un nome DNS, non solo un IP. Scegli un hostname come mail.example.com. Quel nome diventerà il tuo MAILCOW_HOSTNAME, il subject del certificato TLS, il target del PTR e il banner SMTP. Mantieni la coerenza in ogni configurazione.

Step 1 — Verificare che la porta outbound 25 sia aperta

Eseguire questo passaggio per primo. Qualsiasi altra operazione è inutile se il test fallisce. Dal nuovo VPS, tentare di avviare una connessione SMTP con un server di posta reale:

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

Un risultato positivo è immediato:

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

Se la porta è bloccata, il comando rimane in sospeso per cinque secondi e poi fallisce:

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

Il timeout indica il blocco. Si tratta di un filtro di rete lato provider, non del firewall locale; nessuna modifica locale può risolvere il problema. Aprire un ticket di assistenza: "Please enable outbound TCP port 25 for my VPS at <IP>; I am running a legitimate mail server." Non installare mailcow finché il test non restituisce "succeeded". Si noti che la porta 25 inbound (i server che contattano il VPS) è un percorso separato ed è solitamente aperta; è il traffico outbound che i provider limitano.

Step 2 — Configurare ora i record DNS

Le modifiche DNS richiedono tempo per la propagazione. Pubblica tutti i record possibili prima di procedere con l'installazione. Assumi che il tuo dominio sia example.com, il tuo host mail sia mail.example.com e l'IP sia 10.0.0.10. Nella tua zona, crea:

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"

Il record SPF indica che "solo il mio MX può inviare per questo dominio, rifiuta gli altri". Imposta DMARC a p=none per monitorare i report senza causare il bounce della propria posta; passa a p=quarantine e poi a p=reject una volta confermata l'allineamento. Mancano intenzionalmente due record: DKIM, che mailcow genera automaticamente nello Step 6, e PTR, che devi configurare ora nel pannello del tuo provider.

Imposta il PTR (reverse DNS) per 10.0.0.10 su mail.example.com — il valore esatto di MAILCOW_HOSTNAME. Questo è il record che la maggior parte degli utenti dimentica e i grandi provider lo rifiutano. Se il tuo pannello non dispone di un campo rDNS, apri un ticket di assistenza.

Step 3 — Install Docker

mailcow richiede Docker Engine con il plugin Compose v2. Utilizza lo script ufficiale di Docker invece del pacchetto docker.io di Ubuntu, poiché quest'ultimo non include il plugin Compose:

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

Dovresti vedere una riga Docker Compose version v2.x. Se docker compose version stampa docker: 'compose' is not a docker command, Docker Engine è installato ma il plugin Compose non lo è. Installa il plugin dal repository di Docker: esegui nuovamente lo script sopra riportato, oppure segui la nostra guida ai concetti base di Docker Compose, che configura entrambi tramite il repository apt ufficiale di Docker.

Step 4 — Clone mailcow e genera la configurazione

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

Verifica che umask restituisca 0022. mailcow fallisce la build se la maschera dei file è errata; una shell root su Ubuntu 24.04 fornisce già 0022. Lo script richiede poi l'unico dato fondamentale: l'hostname fully qualified. Inserisci mail.example.com; il valore deve corrispondere esattamente al record A e al record PTR. Lo script scrive mailcow.conf, l'unico file di ambiente utilizzato dall'intero stack. Apri il file se devi modificare le porte web (HTTP_PORT, HTTPS_PORT) o disabilitare ClamAV su sistemi con risorse limitate:

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 è l'altra opzione per sistemi con poca RAM: la ricerca full-text è il secondo componente che consuma più memoria secondo la documentazione di mailcow; disabilitarla comporta solo la perdita della ricerca nel corpo del testo via webmail.

Lascia invariati HTTP_PORT=80 e HTTPS_PORT=443 a meno che altri servizi sull'host non li utilizzino già. Il client ACME integrato in mailcow richiede che la porta 80 sia raggiungibile da internet per ottenere il certificato. Per questo motivo non si deve eseguire una configurazione separata nginx-plus-Certbot sullo stesso server; mailcow gestisce l'emissione e il rinnovo dei propri certificati TLS internamente, e un secondo servizio sulla porta 80/443 impedisce questo processo.

Step 5 — Avviare lo stack e effettuare il login

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

Il comando pull scarica circa due decine di immagini; attendere alcuni minuti. Quando docker compose ps mostra ogni container running (o healthy), aprire https://mail.example.com in un browser. Le credenziali di amministrazione predefinite sono username admin e password moohoo. Modificare immediatamente la password nell'interfaccia admin sotto Access → Administrators. Se il browser segnala NET::ERR_CERT_AUTHORITY_INVALID, il certificato ACME non è ancora stato emesso; consultare la sezione relativa ai fallimenti ACME prima di considerare il sistema guasto; un certificato self-signed temporaneo è normale per i primi uno o due minuti.

Step 6 — Aggiungere un dominio, una casella postale e pubblicare DKIM

Nell'interfaccia di amministrazione, apri la pagina Mail Setup (Configuration → Mail Setup). Sotto la scheda Domains, clicca su Add domain e inserisci example.com. Successivamente, sotto Mailboxes, clicca su Add mailbox per creare you@example.com con una password. La casella è operativa e già raggiungibile tramite IMAP.

Passiamo alla chiave DKIM. Vai su Configuration → ARC/DKIM keys; mailcow potrebbe aver già generato una chiave durante l'aggiunta del dominio. In caso contrario, generane una nuova: seleziona il dominio, mantieni il selector dkim, scegli 2048-bit e clicca su Add. Copia il valore TXT generato e pubblicalo come segue:

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

La pagina Domains di mailcow dispone di un pulsante DNS che elenca tutti i record richiesti e indica lo stato di pubblicazione tramite un segno di spunta verde o una croce rossa. Utilizzalo come checklist: tutti i record devono essere verdi prima di testare la deliverability. Una riga DKIM rossa dopo la pubblicazione indica solitamente che la chiave è stata suddivisa in segmenti TXT errati; una chiave a 2048-bit supera il limite di 255 caratteri per una singola stringa TXT. Incolla la chiave come un unico valore logico e lascia che il tuo host DNS la suddivida in segmenti automaticamente.

Step 7 — Test deliverability and chase 10/10

Vai su mail-tester.com, copia l'indirizzo casuale visualizzato e invia un messaggio da tua nuova casella postale — effettua il login in SOGo webmail su https://mail.example.com/SOGo e invia da lì. Successivamente, clicca su "Then check your score".

L'obiettivo è ottenere 10/10. Le cause comuni di penalizzazione sono:

  • SPF not aligned — il record MX/SPF è assente o l'IP di invio non è incluso. Verifica nuovamente il record SPF TXT.
  • DKIM signature does not verify — il record dkim._domainkey TXT è assente, in fase di propagazione o corrotto. Questo è l'errore più comune.
  • No PTR / PTR mismatch — il DNS inverso non risolve verso mail.example.com. Risolvi il problema tramite il provider.
  • Listed on a blocklist — reputazione precedente dell'IP. Richiedi la rimozione dalla blocklist o richiedi un IP con reputazione migliore.

Non inviare email reali a Gmail o Outlook finché il punteggio non è 10/10. Un punteggio basso combinato con un nuovo IP causa il flagging del dominio fin dal primo giorno.

Step 8 — Connetti un client mail reale

Configura Thunderbird, Apple Mail o il tuo smartphone verso il server utilizzando queste impostazioni. L'host del server è mail.example.com per tutti i client:

  • IMAP: porta 993, SSL/TLS (o 143 con STARTTLS)
  • SMTP submission: porta 465, SSL/TLS (o 587 con STARTTLS)
  • Username: l'indirizzo completo, you@example.com
  • Password: la password della casella postale impostata in precedenza

Non inviare mai email tramite il client sulla porta 25. La porta 25 è riservata esclusivamente alla comunicazione server-to-server; mailcow non supporta l'invio autenticato su questa porta e le connessioni dei client vengono rifiutate. Se il client restituisce l'errore Relay access denied, sta tentando l'invio sulla porta 25 o senza autenticazione; passa alla porta 465 o 587 utilizzando le credenziali della casella postale.

Step 9 — Back up what actually matters

mailcow include uno script di backup che crea snapshot di ogni volume stateful. Eseguilo su un disco esterno o su un volume remoto montato:

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

all salva sei elementi; la perdita di uno di essi comporta la perdita dei dati: vmail (le mailbox), crypt (le chiavi per decriptare vmail — inutili senza di esse), mysql (il database MariaDB con domini, utenti, alias e impostazioni), redis (lo stato di code e cache), rspamd (le informazioni apprese su spam/ham) e postfix (la coda di posta). Lo script viene eseguito all'interno di un container helper che scrive archivi compressi; i backup rimangono consistenti anche con lo stack attivo. Automatizza il processo con un cron job notturno e aggiungi --delete-days 14 per eliminare i set obsoleti. Il ripristino utilizza lo stesso script con restore, che elenca gli snapshot e permette di selezionare cosa ripristinare. Un backup che non è mai stato testato per il ripristino è solo una speranza, non un backup — esegui una prova su un VPS di test.

Step 10 — Update on a schedule

mailcow esegue gli aggiornamenti tramite il proprio script. Lo script scarica il nuovo codice, esegue la migrazione di mailcow.conf, preleva le immagini e riavvia i container nell'ordine indicato:

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

Eseguire prima il backup (Step 9), poiché la migrazione dello schema non è facilmente reversibile. Gli aggiornamenti sono frequenti e includono correzioni di sicurezza per i daemon esposti su internet; non lasciare che un server mail rimanga senza aggiornamenti per mesi. Se un aggiornamento causa lo stato unhealthy di un container, sudo docker compose logs --tail=50 <service>-mailcow indica il daemon che non è riuscito a riavviarsi.

Una nota sul hardening

mailcow utilizza un proprio servizio netfilter (netfilter-mailcow) che banna gli IP che effettuano tentativi ripetuti sulle porte mail e webmail; la parte mail è quindi protetta di default. Questa protezione non copre SSH sull'host, che rimane esposto e soggetto a attacchi brute-force. Si consiglia di combinare questa configurazione con Fail2ban che monitora il log di autenticazione SSH e l'accesso tramite chiavi SSH. Proteggi l'interfaccia admin di mailcow con una password robusta e, idealmente, tienila fuori dalla rete pubblica o dietro una VPN.

Modalità di errore, con le stringhe esatte

Code di posta e mancata consegna. Esegui sudo docker compose exec postfix-mailcow postqueue -p, oppure consulta la mail queue nell'interfaccia di amministrazione; le voci risultano deferred con:

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

Il provider blocca la porta 25 in uscita (Step 1). Nessuna configurazione può risolvere il problema — apri un ticket di assistenza. Non si tratta di DNS o TLS; l'indicatore è la parola timed out riferita a un MX remoto sulla porta 25.

Gmail contrassegna tutto come spam o lo rifiuta. Apri il messaggio in Gmail, seleziona "Mostra originale" e leggi i risultati di autenticazione. dkim=fail o dkim=none indicano che il record TXT dkim._domainkey è mancante, errato o non ancora propagato — pubblica esattamente quanto indicato nella pagina ARC/DKIM e attendi il TTL. spf=fail indica che i record SPF/MX non coprono il tuo IP. L'allineamento è fondamentale; un solo controllo fallito è sufficiente per finire nello spam.

Rifiuto da parte di grandi provider durante la connessione. I bounce o i log di Postfix riportano il rifiuto PTR di 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.

Il codice 550 5.7.25 indica la mancanza o il disallineamento del DNS inverso. Imposta il PTR per il tuo IP su mail.example.com tramite il provider (Step 2). Il record Forward (A) e il record Reverse (PTR) devono coincidere, e entrambi devono indicare lo stesso hostname con cui mailcow contatta gli altri server.

Il browser mostra un avviso di certificato che non scompare. Il container acme-mailcow non è riuscito a ottenere un certificato valido. Controlla il relativo log:

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

Una riga come Cannot validate any hostnames, skipping Let's Encrypt for 1 hour. o un fallimento della challenge indicano che la porta 80 non è raggiungibile da internet, oppure che il record A non punta a questo server. Verifica che mail.example.com risolva verso il server, apri le porte 80 e 443 su ogni firewall dell'host e assicurati che nessun altro servizio utilizzi tali porte. Dopo aver risolto la causa, riavvia il client con sudo docker compose restart acme-mailcow invece di attendere il tempo di back-off di un'ora.

FAQ

L'auto-hosting di email ne vale davvero la pena?

Se desideri la proprietà dei dati, alias illimitati e il controllo totale, la risposta è sì: mailcow fornisce uno stack professionale al costo di un VPS. Tuttavia, la deliverability richiede un impegno costante: la reputazione dell'IP, l'allineamento DNS e il monitoraggio delle blocklist sono attività continue. Per un indirizzo aziendale critico, dove un solo giorno nella cartella spam causa perdite economiche, un provider gestito è la scelta più pragmatica. Scegli l'auto-hosting se preferisci il controllo alla comodità e se sei disposto a gestirlo attivamente.

Come posso sapere se la porta 25 in uscita è bloccata?

Esegui nc -vz -w 5 gmail-smtp-in.l.google.com 25 dal server. Il messaggio "succeeded!" indica che la porta è aperta; un timed out dopo la pausa indica che il provider la blocca. Questo è il motivo più comune per cui un server self-hosted può ricevere email ma non inviarle; l'unica soluzione è la richiesta al provider di aprire la porta, poiché nessuna modifica locale può risolvere il problema.

Perché le mie email finiscono ancora nello spam di Gmail?

Quasi sempre a causa di una catena di autenticazione interrotta. Usa l'opzione "Mostra originale" in Gmail e cerca spf=pass, dkim=pass e dmarc=pass. Un dkim=fail indica un record TXT dkim._domainkey mancante o errato; anche un mismatch del PTR o un nuovo IP senza cronologia di invio compromettono la reputazione. Ottieni un punteggio di 10/10 su mail-tester.com e poi scalda l'IP lentamente — inviando pochi messaggi al giorno fino a raggiungere volumi maggiori — invece di inviare grandi quantità di posta il primo giorno.

Cosa devo backuppare esattamente?

Esegui backup_and_restore.sh backup all e conserva l'intero set al di fuori del server. Il backup include vmail (le caselle postali), crypt (le chiavi per la decrittazione), il database MariaDB (domini, utenti, alias, impostazioni), Redis, i dati appresi di Rspamd e la coda di Postfix. Il volume crypt è quello che spesso viene trascurato: senza di esso, il backup di vmail è un testo cifrato illeggibile. Testa il ripristino su una macchina di prova almeno una volta.

Posso eseguire mailcow su un VPS da 2 GB?

Non in modo confortevole. generate_config.sh suggerisce di disabilitare ClamAV se si dispone di meno di circa 2.5 GiB; anche in questo caso, Rspamd, ClamAV, Dovecot e MariaDB competono per la memoria, causando l'uso dello swap e l'OOM kill sotto carico reale. Considera 6 GiB più 1 GiB di swap come il limite minimo per un'installazione stabile per un singolo utente; passa a 8 GiB non appena più di due persone iniziano a utilizzarlo.

#mailcow#email#self-hosting#docker#dns