SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-29

Pasang mailcow di VPS agar email diterima Gmail

Uji port outbound 25 sebelum memasang mailcow. Jika diblokir, email tertahan di antrean. Atur DNS untuk mencegah penolakan Gmail 550 5.7.25 akibat PTR.

Yang akan Anda bangun

Server email lengkap pada server yang Anda miliki: SMTP untuk mengirim dan menerima email, IMAP agar ponsel dan laptop tetap tersinkronisasi, klien webmail, serta filter spam yang memberikan skor pada setiap pesan untuk kedua arah. mailcow-dockerized menggabungkan Postfix, Dovecot, Rspamd, webmail SOGo, MariaDB, Redis, dan klien ACME ke dalam satu stack Docker Compose, sehingga perangkat lunak bukan bagian yang sulit. Server akan berjalan dalam waktu setengah jam.

Bagian yang sulit adalah semua hal di sekitarnya. Email adalah satu-satunya layanan yang membuat server baru secara aktif tidak dipercaya oleh Internet lainnya. Perbedaan antara "berfungsi" dan "Gmail diam-diam menghapus setiap pesan" bergantung pada empat record DNS dan satu pengaturan reputasi IP yang mungkin tidak sepenuhnya dapat Anda kendalikan. Baca prasyarat di bawah ini sebelum menyewa server. Jika setelah membacanya Anda memutuskan bahwa proses membangun reputasi tidak sepadan, itu adalah keputusan yang sah. ringkasan kami tentang hal-hal yang benar-benar layak di-self-host pada 2026 menempatkan email dalam kategori "hanya jika Anda benar-benar menginginkannya" karena alasan-alasan tersebut.

Prasyarat ADALAH proyek

Jika salah satu saja terlewat, Anda akan mengirim email yang tidak pernah sampai. Berikut urutannya secara umum, mulai dari hal yang paling sering menyebabkan masalah:

Port outbound 25 harus terbuka. Server Anda mengirimkan email ke Gmail dan Microsoft melalui TCP port 25. Banyak penyedia VPS dan cloud memblokir port outbound 25 secara default untuk mencegah spam. Pemblokiran ini biasanya tidak terlihat: tidak ada error saat boot, semuanya tampak normal, tetapi email hanya menumpuk di queue tanpa batas. Uji port ini sebelum menginstal apa pun. Jika diblokir, satu-satunya solusi adalah mengirim support ticket untuk meminta penyedia membuka port tersebut. Beberapa penyedia melakukannya untuk akun yang sudah lama aktif, tetapi sebagian lainnya tidak akan pernah membukanya.

IP yang bersih dengan reputasi yang dapat digunakan. IP VPS daur ulang sering sudah masuk blocklist karena spam dari tenant sebelumnya. Periksa IP Anda melalui layanan seperti Spamhaus lookup atau mxtoolbox sebelum melanjutkan. IP yang terdaftar akan menyebabkan penolakan yang tidak dapat diatasi hanya dengan mengubah kode.

Kendali atas DNS serta record PTR yang benar. Anda perlu menambahkan record ke zone domain, dan perlu reverse DNS (PTR) untuk IP server yang mengarah kembali ke hostname email. PTR hampir tidak pernah dikonfigurasi di DNS panel Anda. Record ini dikelola oleh pihak yang memiliki IP, sehingga pengaturannya dilakukan melalui control panel penyedia VPS atau melalui ticket.

RAM 6 GiB dan 2 vCPU adalah batas minimum yang nyaman. Minimum yang ditetapkan mailcow sendiri adalah RAM 6 GiB ditambah swap 1 GiB untuk instalasi privat. RAM 8 GiB disarankan jika sudah ada beberapa pengguna yang mengandalkannya. Jika RAM kurang dari sekitar 2.5 GiB, generate_config.sh akan menawarkan untuk menonaktifkan virus scanner ClamAV agar kernel tidak mulai menghentikan container. Sediakan SSD 20 GB sejak awal.

Nama DNS, bukan IP biasa. Pilih hostname seperti mail.example.com. Satu nama ini menjadi MAILCOW_HOSTNAME, subject sertifikat TLS, target PTR, dan banner SMTP Anda. Gunakan nama yang sama secara konsisten di semua konfigurasi.

Langkah 1, Pastikan port keluar 25 terbuka

Lakukan ini terlebih dahulu. Langkah lain tidak akan berguna jika pemeriksaan ini gagal. Dari VPS baru, coba buka percakapan SMTP dengan server email nyata:

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

Hasil yang berhasil akan segera muncul:

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

Port yang diblokir akan menunggu selama lima detik, lalu gagal:

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

Batas waktu tersebut menunjukkan adanya pemblokiran. Ini adalah filter jaringan dari provider, bukan firewall Anda, sehingga tidak dapat diperbaiki dengan perubahan lokal. Buka tiket dengan pesan berikut: "Please enable outbound TCP port 25 for my VPS at <IP>; I am running a legitimate mail server." Jangan menginstal mailcow sebelum perintah ini mengembalikan "succeeded". Perhatikan bahwa port masuk 25 (server lain yang terhubung ke server Anda) merupakan jalur terpisah dan biasanya terbuka. Provider biasanya membatasi koneksi keluar.

Langkah 2, Tetapkan record DNS sekarang

Perubahan DNS memerlukan waktu untuk dipropagasikan, jadi publikasikan semua record yang dapat Anda siapkan sebelum melakukan instalasi. Misalkan domain Anda adalah example.com, host mail Anda adalah mail.example.com, dan IP-nya adalah 10.0.0.10. Buat record berikut di zone DNS Anda:

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"

Record SPF menyatakan bahwa "hanya MX saya yang boleh mengirim untuk domain ini; tolak pengirim lainnya". Mulai DMARC dengan p=none agar Anda dapat memantau laporan tanpa menolak email Anda sendiri. Setelah alignment terbukti, perketat kebijakan tersebut menjadi p=quarantine, lalu p=reject. Dua record sengaja belum dibuat: DKIM, yang akan dibuatkan oleh mailcow pada Langkah 6, dan PTR, yang harus Anda tetapkan sekarang di panel provider.

Tetapkan PTR (reverse DNS) untuk 10.0.0.10 ke mail.example.com, yaitu nilai persis MAILCOW_HOSTNAME. Ini adalah satu-satunya record yang paling sering dilupakan, dan provider besar akan menolak email berdasarkan record ini. Jika panel Anda tidak memiliki kolom rDNS, buat tiket dukungan.

Langkah 3, Instal Docker

mailcow memerlukan Docker Engine dengan plugin Compose v2. Gunakan skrip praktis resmi dari Docker, bukan paket docker.io Ubuntu, karena paket tersebut tidak menyediakan plugin Compose:

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

Anda akan melihat baris Docker Compose version v2.x. Jika docker compose version menampilkan docker: 'compose' is not a docker command, Docker Engine sudah terinstal, tetapi plugin Compose belum tersedia. Instal plugin tersebut dari repositori Docker, jalankan kembali skrip di atas, atau ikuti panduan dasar Docker Compose kami, yang menyiapkan keduanya dari repositori apt milik Docker.

Langkah 4, Clone mailcow dan buat konfigurasi

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

Pastikan umask menampilkan 0022 terlebih dahulu. mailcow menolak proses build jika file mask tidak sesuai. Shell root baru pada Ubuntu 24.04 sudah menetapkan 0022. Selanjutnya, skrip meminta satu hal yang penting: hostname yang sepenuhnya memenuhi syarat. Masukkan mail.example.com. Nilainya harus sama persis dengan A record dan PTR Anda. Skrip menulis mailcow.conf, yaitu satu-satunya file lingkungan yang dibaca oleh seluruh stack. Buka file tersebut jika Anda perlu mengubah port web (HTTP_PORT, HTTPS_PORT) atau menonaktifkan ClamAV pada server dengan sumber daya terbatas:

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 adalah pengaturan lain yang penting pada server dengan RAM kecil. Pencarian teks lengkap merupakan penyebab kedua penggunaan memori tinggi yang disebut dalam dokumentasi mailcow. Menonaktifkannya hanya menghilangkan pencarian isi pesan di webmail.

Biarkan HTTP_PORT=80 dan HTTPS_PORT=443, kecuali layanan lain pada host sudah menggunakannya. Klien ACME bawaan mailcow memerlukan port 80 yang dapat dijangkau dari Internet untuk memperoleh sertifikat. Karena itu, jangan jalankan setup nginx-plus-Certbot terpisah pada server yang sama. mailcow menerbitkan dan memperbarui TLS secara internal, sedangkan layanan kedua yang menggunakan port 80/443 akan menyebabkan konflik. Hal yang sama berlaku untuk layanan lain yang memerlukan front end web publik. Karena itu, build seperti Halcyon yang mengubah tampilan pustaka Jellyfin menjadi toko video era 90-an, yang mengharapkan reverse proxy sendiri pada port 443, harus ditempatkan pada host lain. Pengecualiannya adalah layanan yang tidak pernah meminta port web publik: relay RustDesk yang di-host sendiri hanya mendengarkan pada rentang port 21115 hingga 21119 miliknya, sehingga dapat berbagi server selama bandwidth yang tersedia masih mencukupi.

Langkah 5, Jalankan stack dan masuk

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

Perintah pull mengunduh sekitar dua lusin image; tunggu beberapa menit. Setelah docker compose ps menampilkan semua container dalam status running (atau healthy), buka https://mail.example.com di browser. Kredensial admin default adalah username admin dan password moohoo. Segera ubah password tersebut di UI admin melalui Access → Administrators. Jika browser menampilkan peringatan NET::ERR_CERT_AUTHORITY_INVALID, sertifikat ACME belum diterbitkan. Lihat bagian tentang kegagalan ACME di bawah sebelum menganggap konfigurasinya bermasalah; sertifikat placeholder yang ditandatangani sendiri adalah kondisi normal selama satu atau dua menit pertama.

Langkah 6, Tambahkan domain, mailbox, dan publikasikan DKIM

Di UI admin, buka halaman Mail Setup (Configuration → Mail Setup). Pada tab Domains, klik Add domain dan masukkan example.com. Selanjutnya, pada bagian Mailboxes, klik Add mailbox untuk membuat you@example.com dengan kata sandi. Mailbox tersebut sudah dapat digunakan dan diakses melalui IMAP.

Berikutnya, buat kunci DKIM. Buka Configuration → ARC/DKIM keys. mailcow mungkin sudah membuat kunci saat Anda menambahkan domain. Jika belum, buat kunci di halaman tersebut, pilih domain, pertahankan selector dkim, pilih 2048-bit, lalu klik Add. Salin nilai TXT panjang yang ditampilkan dan publikasikan sebagai:

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

Halaman Domains di mailcow memiliki tombol DNS yang mencantumkan setiap record yang diharapkan serta menampilkan tanda centang hijau atau silang merah berdasarkan record yang benar-benar sudah dipublikasikan. Gunakan daftar tersebut sebagai checklist. Pastikan semua baris berwarna hijau sebelum menguji deliverability. Baris DKIM berwarna merah setelah publikasi biasanya berarti kunci dipecah menjadi beberapa bagian TXT secara tidak benar. Kunci 2048-bit lebih panjang daripada batas 255 karakter untuk satu string TXT. Tempelkan kunci sebagai satu nilai logis dan biarkan host DNS Anda memecahnya menjadi beberapa bagian.

Langkah 7, Uji keterkiriman dan kejar skor 10/10

Buka mail-tester.com, salin alamat acak yang ditampilkan, lalu kirim pesan ke alamat tersebut dari mailbox baru Anda. Masuk ke webmail SOGo di https://mail.example.com/SOGo dan kirim pesan dari sana. Kemudian klik "Then check your score".

Targetkan skor 10/10. Pengurangan skor yang umum beserta penyebabnya:

  • SPF tidak selaras, record MX/SPF Anda tidak ada atau IP pengirim tidak tercakup. Periksa kembali TXT SPF.
  • Tanda tangan DKIM tidak dapat diverifikasi, TXT dkim._domainkey tidak ada, masih dalam proses propagasi, atau rusak. Ini adalah kesalahan yang paling sering terjadi.
  • Tidak ada PTR / PTR tidak cocok, reverse DNS tidak me-resolve ke mail.example.com. Perbaiki di provider.
  • Terdaftar di blocklist, IP Anda memiliki reputasi sebelumnya yang buruk. Ajukan penghapusan dari daftar atau minta IP yang reputasinya lebih bersih.

Jangan kirim email sungguhan ke Gmail atau Outlook sebelum hasil ini menunjukkan skor 10/10. Skor rendah ditambah IP baru dapat menyebabkan domain Anda ditandai sejak hari pertama.

Langkah 8, Hubungkan klien email sebenarnya

Arahkan Thunderbird, Apple Mail, atau ponsel Anda ke server menggunakan pengaturan berikut. Host server untuk semuanya adalah mail.example.com:

  • IMAP: port 993, SSL/TLS (atau 143 dengan STARTTLS)
  • Pengiriman SMTP: port 465, SSL/TLS (atau 587 dengan STARTTLS)
  • Nama pengguna: alamat lengkap, you@example.com
  • Kata sandi: kata sandi mailbox yang Anda tetapkan

Jangan pernah mengirim email klien melalui port 25. Port tersebut hanya digunakan untuk komunikasi antarpeladen. mailcow tidak menyediakan pengiriman terautentikasi pada port tersebut, sehingga koneksi dari klien yang diarahkan ke port 25 akan ditolak. Jika klien melaporkan Relay access denied, klien tersebut mencoba mengirim melalui port 25 atau tanpa autentikasi. Alihkan ke port 465 atau 587 dan gunakan kredensial mailbox Anda.

Langkah 9, Cadangkan data yang benar-benar penting

mailcow menyediakan skrip pencadangan yang membuat snapshot untuk setiap volume stateful. Jalankan skrip ini ke disk eksternal atau penyimpanan remote yang di-mount:

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

all mencadangkan enam hal. Kehilangan salah satunya berarti kehilangan data: vmail (mailbox yang sebenarnya), crypt (key yang mendekripsi vmail dan tidak berguna tanpa vmail), mysql (MariaDB yang menyimpan domain, user, alias, dan pengaturan), redis (status antrean dan cache), rspamd (data spam/ham yang telah dipelajari), serta postfix (antrean email). Skrip ini berjalan di dalam helper container dan menulis arsip terkompresi. Dengan demikian, backup tetap konsisten meskipun stack sedang berjalan. Otomatiskan proses ini dengan cron job setiap malam, lalu tambahkan --delete-days 14 untuk menghapus set lama. Cron job yang berhenti bekerja akan gagal secara diam-diam. Karena itu, kirim status keluar skrip ke tempat yang benar-benar akan Anda perhatikan. server ntfy yang di-host sendiri dapat menerima satu baris curl dari cron entry yang sama dan mengirimkan notifikasi kegagalan ke ponsel Anda pada malam saat kegagalan terjadi. Restore menggunakan skrip yang sama dengan restore. Opsi ini menampilkan snapshot dan memungkinkan Anda memilih data yang akan dipulihkan. Backup yang belum pernah diuji dengan restore hanyalah harapan, bukan backup. Lakukan satu dry run ke VPS sementara terlebih dahulu.

Langkah 10, Perbarui secara berkala

mailcow diperbarui melalui skripnya sendiri. Skrip ini mengambil kode baru, memigrasikan mailcow.conf, melakukan prefetch image, lalu me-restart container secara berurutan:

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

Buat backup terlebih dahulu (Langkah 9), karena migrasi skema sulit dibatalkan. Pembaruan sering dirilis dan mencakup perbaikan keamanan untuk daemon yang menghadap Internet. Karena itu, jangan biarkan mail server tidak diperbarui selama berbulan-bulan. Jika pembaruan menyebabkan container berstatus tidak sehat, sudo docker compose logs --tail=50 <service>-mailcow menunjukkan nama daemon yang gagal berjalan kembali.

Catatan tentang hardening

mailcow menjalankan service netfilter sendiri (netfilter-mailcow) yang memblokir IP yang terus-menerus menyerang port mail dan webmail. Dengan demikian, sisi mail sudah dilindungi secara bawaan. Namun, perlindungan ini tidak mencakup SSH pada host itu sendiri. SSH tetap terekspos dan masih menjadi sasaran brute-force. Lengkapi build ini dengan Fail2ban yang memantau log autentikasi SSH dan login yang hanya menggunakan key. Lindungi UI admin mailcow dengan password yang kuat dan, idealnya, jangan ekspos UI tersebut ke Internet publik atau tempatkan di balik VPN.

Mode kegagalan, dengan string yang persis

Antrean email tidak pernah terkirim. Jalankan sudo docker compose exec postfix-mailcow postqueue -p, atau baca antrean email pada UI admin; entri tetap berstatus tertunda dengan:

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

Itu berarti port outbound 25 diblokir oleh provider Anda (Langkah 1). Tidak ada perubahan konfigurasi yang dapat memperbaikinya; buka tiket dukungan. Masalahnya bukan DNS dan bukan TLS; indikatornya adalah kata timed out pada MX remote di port 25.

Gmail menandai semua email sebagai spam atau menolaknya. Buka pesan di Gmail, pilih "Show original", lalu baca hasil autentikasi. dkim=fail atau dkim=none berarti TXT dkim._domainkey Anda hilang, rusak, atau belum selesai dipropagasikan. Publikasikan ulang persis seperti yang ditampilkan halaman ARC/DKIM, lalu tunggu TTL. spf=fail berarti record SPF/MX tidak mencakup IP Anda. Alignment sangat penting; satu pemeriksaan yang gagal sudah cukup untuk membuat email masuk ke spam.

Ditolak provider besar saat koneksi dibuat. Bounce atau log Postfix memuat penolakan PTR dari 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.

Kode 550 5.7.25 berarti reverse DNS hilang atau tidak cocok. Atur PTR untuk IP Anda menjadi mail.example.com di provider (Langkah 2). Forward (A) dan reverse (PTR) harus cocok, dan keduanya harus menyebut host yang sama dengan nama yang digunakan mailcow saat menyapa server lain.

Browser menampilkan peringatan sertifikat yang tidak pernah hilang. Container acme-mailcow gagal memperoleh sertifikat yang valid. Periksa log-nya:

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

Baris seperti Cannot validate any hostnames, skipping Let's Encrypt for 1 hour. atau kegagalan challenge berarti port 80 tidak dapat dijangkau dari Internet, atau record A tidak mengarah ke server ini. Pastikan mail.example.com mengarah ke server tersebut, buka port 80 dan 443 melalui firewall host yang digunakan, dan pastikan tidak ada proses lain yang menggunakan port tersebut. Setelah penyebabnya diperbaiki, restart client dengan sudo docker compose restart acme-mailcow, bukan menunggu masa back-off selama satu jam berakhir.

FAQ

Apakah self-hosting email benar-benar sepadan?

Jika Anda menginginkan kepemilikan data, alias tanpa batas, dan kendali penuh, ya, mailcow menyediakan stack profesional dengan biaya setara VPS. Namun, menjaga deliverability adalah pekerjaan yang terus berlangsung: reputasi IP, keselarasan DNS, dan pemantauan blocklist tidak pernah benar-benar selesai. Untuk alamat bisnis yang sangat penting, ketika satu hari email berada di folder spam seseorang dapat merugikan Anda, provider terkelola adalah pilihan yang praktis. Gunakan self-hosting jika Anda lebih mengutamakan kendali daripada kenyamanan dan benar-benar bersedia mengelolanya. Jika tujuan utama Anda adalah menyimpan data di luar server milik pihak lain, bukan email secara khusus, mulailah dari layanan yang tidak dapat dikendalikan orang lain: photo library sama sekali tidak memiliki masalah deliverability, dan perbandingan PhotoPrism dan Immich kami membahas kebutuhan minimum RAM serta command backup untuk build tersebut pada jenis VPS yang sama.

Bagaimana cara mengetahui apakah port outbound 25 diblokir?

Jalankan nc -vz -w 5 gmail-smtp-in.l.google.com 25 dari server. Pesan "succeeded!" berarti port tersebut terbuka; timed out setelah jeda berarti provider Anda memblokirnya. Ini adalah alasan paling umum mengapa server self-hosted dapat menerima email tetapi tidak pernah dapat mengirimnya, dan satu-satunya solusinya adalah provider membuka port tersebut; tidak ada perubahan pada pengaturan lokal yang dapat membukanya.

Mengapa email saya masih masuk ke folder spam Gmail?

Hampir selalu karena rantai autentikasi yang rusak. Gunakan "Show original" di Gmail dan cari spf=pass, dkim=pass, serta dmarc=pass. dkim=fail menunjukkan bahwa record TXT dkim._domainkey hilang atau salah; ketidaksesuaian PTR atau IP baru yang belum memiliki riwayat pengiriman juga berdampak buruk. Dapatkan skor 10/10 di mail-tester.com terlebih dahulu, lalu lakukan pemanasan IP secara bertahap, mulai dari beberapa pesan per hari dan tingkatkan jumlahnya, bukan langsung mengirim volume besar pada hari pertama.

Apa saja yang sebenarnya perlu saya backup?

Jalankan backup_and_restore.sh backup all dan simpan seluruh hasilnya di luar server. Backup ini mencakup vmail (mailbox), crypt (key yang mendekripsi mailbox), database MariaDB (domain, user, alias, dan pengaturan), Redis, data yang dipelajari Rspamd, serta queue Postfix. Volume crypt sering terlewat; tanpa volume tersebut, backup vmail tidak dapat dibaca karena berupa ciphertext. Uji pemulihan ke scratch box setidaknya satu kali.

Apakah mailcow dapat dijalankan pada VPS 2 GB?

Tidak dengan nyaman. generate_config.sh menawarkan penonaktifan ClamAV jika RAM kurang dari sekitar 2.5 GiB, tetapi Rspamd, ClamAV, Dovecot, dan MariaDB tetap berebut memori. Akibatnya, swap dan OOM kill akan terjadi saat ada beban nyata. Anggap 6 GiB ditambah 1 GiB swap sebagai batas minimum untuk instalasi single-user yang stabil, lalu beralih ke 8 GiB segera setelah lebih dari beberapa orang mengandalkannya.