Latar Belakang
Kebutuhan kali ini yang ingin dicoba adalah infrastruktur email profesional dan hosting untuk kebutuhan dua domain. Daripada bergantung pada layanan email pihak ketiga, saya putuskan untuk membangun mail server sendiri menggunakan Stalwart — mail server modern berbasis Rust yang ringan dan feature-complete.
Spesifikasi VPS
VPS yang digunakan menggunakan spesifikasi yang minim dengan detail:
- CPU: 2 vCPU
- RAM: 2GB
- Storage: 20GB SSD
- OS: Ubuntu 22.04 LTS
- IP Publik: 1 IP dedicated
Spesifikasi ini lebih dari cukup untuk Coolify + Stalwart + beberapa website kecil.
Stack yang Dipakai
VPS Ubuntu 22.04 ├── Coolify 4.1.2 (panel manajemen) │ └── Traefik v3.6 (reverse proxy + SSL otomatis) ├── Stalwart Mail Server (Docker) │ ├── Domain: domainpertama.id │ └── Domain: domainkedua.id └── Snappymail (webmail client)
Install Docker
curl -fsSL https://get.docker.com | sh systemctl enable --now docker
Install Coolify
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
Setelah install selesai, Coolify bisa diakses di http://IP_VPS:8000. Setup domain coolify.domainpertama.id via Settings → URL.
Setup Firewall
ufw allow 22/tcp ufw allow 80/tcp ufw allow 443/tcp ufw allow 25/tcp ufw allow 587/tcp ufw allow 993/tcp ufw --force enable
Install Stalwart Mail Server
Buat folder dan docker-compose:
mkdir -p /opt/stalwart nano /opt/stalwart/docker-compose.yml
services:
stalwart:
image: stalwartlabs/stalwart:latest
container_name: stalwart
restart: unless-stopped
ports:
- "25:25"
- "587:587"
- "465:465"
- "143:143"
- "993:993"
- "4190:4190"
- "8081:8080"
volumes:
- /opt/stalwart/data:/opt/stalwart
environment:
- TZ=Asia/Jakarta
networks:
- coolify
- default
networks:
coolify:
external: true
cd /opt/stalwart docker compose up
Catat password admin yang muncul di log — hanya muncul sekali!
Setup Reverse Proxy via Traefik
Gabungkan Stalwart ke network Coolify:
docker network connect coolify stalwart
Cek IP container:
docker inspect stalwart | grep -A 5 '"coolify"'
Tambah Dynamic Configuration di Coolify → Servers → localhost → Proxy → Dynamic Configurations:
http:
routers:
stalwart:
rule: "Host(`mail.domainpertama.id`)"
service: stalwart
entryPoints:
- https
tls:
certResolver: letsencrypt
services:
stalwart:
loadBalancer:
servers:
- url: "http://IP_CONTAINER:8080"
DNS Records di Cloudflare
Setelah Stalwart setup dan generate DKIM key, tambahkan semua record dari Zone File Stalwart ke Cloudflare:
- MX →
mail.domainpertama.idpriority 10 - TXT SPF →
v=spf1 mx -all - TXT DKIM → 2 record (ed25519 dan RSA)
- TXT DMARC →
v=DMARC1; p=reject; rua=mailto:admin@domainpertama.id - TXT MTA-STS →
v=STSv1; id=... - SRV → imaps, submissions, jmap, pop3s
- CNAME → autoconfig, autodiscover, mta-sts
Penting: DKIM RSA key panjang harus digabung menjadi 1 string di Cloudflare. Kalau terpotong, DKIM akan invalid dan email masuk spam.
Verifikasi panjang DKIM key:
dig TXT v1-rsa-TANGGAL._domainkey.domainpertama.id +short | wc -c
Harusnya 400+ karakter.
Test Kirim Email
Gunakan curl dengan flag --insecure untuk test via port 465 (SMTPS). Cek Gmail apakah email masuk inbox atau spam, dan lihat header "Show original" untuk cek SPF/DKIM/DMARC pass atau tidak.
Kesimpulan
Stalwart terbukti ringan dan powerful untuk self-hosted mail server skala kecil. Dengan Coolify dan Traefik sebagai panel dan reverse proxy, setup menjadi lebih terstruktur dengan SSL otomatis dari Let's Encrypt.
Poin penting yang sering terlewat: DKIM RSA key harus lengkap di DNS. Key yang terpotong menyebabkan DKIM invalid dan email masuk spam meski SPF dan DMARC sudah pass.