Sebagai orang yang sesekali mengisi tulisan di website ini, saya sebenarnya cukup jarang login ke dashboard Ghost. Karena jarang login, suatu waktu saya sempat lupa password untuk masuk ke dashboard Ghost.

Seperti biasa, saya coba klik tombol Forgot yang ada di halaman login, tepat di dekat kolom password. Tapi ternyata hasilnya malah error.

Setelah saya cek lebih lanjut, penyebabnya adalah konfigurasi mail service di Ghost belum diatur dengan benar. Awalnya saya sempat terpikir untuk menggunakan akun email pribadi sebagai sender mail service. Tapi setelah dipertimbangkan lagi, rasanya kurang profesional kalau notifikasi dari website dikirim menggunakan email pribadi.

Dari situlah akhirnya saya berinisiatif untuk membuat SMTP relay sendiri menggunakan Docker.

Di project ini, saya menggunakan Postfix sebagai SMTP submission relay, Dovecot sebagai backend SASL authentication, dan OpenDKIM sebagai komponen opsional untuk melakukan signing email keluar agar email yang dikirim terlihat lebih valid dan trusted dari sisi sender.

Semua service tersebut dijalankan di atas Docker container.

Docker image untuk SMTP relay ini saya build sendiri dan sudah saya upload ke Docker Hub, sehingga proses deploy-nya bisa dibuat lebih sederhana. Jadi kita tidak perlu build image manual dari awal, cukup pull image yang sudah tersedia lalu jalankan menggunakan Docker Compose.

Image yang digunakan pada tutorial ini adalah:

dotkodotid/smtp-relay:latest
Disclaimer: Tutorial ini membutuhkan pemahaman dasar tentang Docker dan Docker Compose.

Langsung saja ke bagian lab.

Pull Docker Image

Pertama, kita pull image SMTP relay dari Docker Hub:

docker pull dotkodotid/smtp-relay:latest

Membuat Struktur Direktori

Pada contoh ini, saya menggunakan Docker Compose untuk menjalankan container.

Sebelum deploy container, kita perlu membuat struktur direktori terlebih dahulu. Struktur ini digunakan untuk menyimpan file SSL certificate, private key, DKIM key, dan password SMTP.

Jalankan command berikut:

mkdir -p smtp-relay/{certs,secrets}

Masuk ke direktori tersebu:

cd smtp-relay

Menyiapkan File SSL Certificate

Di dalam direktori certs, kita akan menyimpan kombinasi SSL certificate dan private key.

Contoh struktur direktorinya kurang lebih seperti ini:

certs/
└── dotko.id
    ├── fullchain.pem
    └── privkey.pem

Pada contoh ini, saya menggunakan domain dotko.id, sehingga file certificate saya simpan di dalam direktori:

certs/dotko.id/

File yang dibutuhkan:

fullchain.pem
privkey.pem

fullchain.pem adalah file SSL certificate, sedangkan privkey.pem adalah private key dari certificate tersebut.

Menyiapkan File Secret

Selanjutnya, kita perlu menyiapkan direktori secrets.

Direktori ini digunakan untuk menyimpan file sensitif seperti password SMTP dan private key DKIM.

Contoh struktur direktorinya seperti ini:

secrets/
├── dkim_private_key
└── smtp_password

File smtp_password berisi password plaintext yang akan digunakan untuk proses SASL authentication.

Contohnya:

echo 'password-yang-kuat' > secrets/smtp_password

Sedangkan file dkim_private_key berisi private key DKIM. Private key ini bisa dibuat menggunakan DKIM generator atau tool seperti opendkim-genkey.

Contoh menggunakan opendkim-genkey:

opendkim-genkey -b 2048 -d dotko.id -s default

Nantinya private key yang dihasilkan bisa disimpan sebagai:

secrets/dkim_private_key

Pastikan file secret tidak bisa dibaca oleh sembarang user:

chmod 600 secrets/*

Konfigurasi Docker Compose

Setelah struktur direktori dan file pendukung siap, kita lanjut membuat file docker-compose.yml.

Berikut contoh konfigurasi sederhana:

services:
  smtp:
    image: dotkodotid/smtp-relay:latest
    container_name: ghost-smtp-relay
    restart: unless-stopped
    ports:
      - "587:587"
    environment:
      SMTP_DOMAIN: dotko.id
      SMTP_HOSTNAME: mail.dotko.id
      SMTP_USER: noreply@dotko.id
      SMTP_PASSWORD_FILE: /run/secrets/smtp_password
      SMTP_TLS_CERT_FILE: /etc/ssl/dotko.id/fullchain.pem
      SMTP_TLS_KEY_FILE: /etc/ssl/dotko.id/privkey.pem
      SMTP_MYNETWORKS: 127.0.0.0/8
      SMTP_MESSAGE_SIZE_LIMIT: "10485760"

      DKIM_ENABLED: "true"
      DKIM_DOMAIN: dotko.id
      DKIM_SELECTOR: default
      DKIM_PRIVATE_KEY_FILE: /run/secrets/dkim_private_key
    volumes:
      - ./certs/dotko.id:/etc/ssl/dotko.id:ro
    secrets:
      - smtp_password
      - dkim_private_key

secrets:
  smtp_password:
    file: ./secrets/smtp_password
  dkim_private_key:
    file: ./secrets/dkim_private_key

Penjelasan Environment Variable

Ada beberapa environment variable yang perlu diperhatikan agar SMTP relay ini bisa berjalan dengan benar.

Konfigurasi Utama SMTP

VariableKeterangan
SMTP_DOMAINDomain default yang digunakan untuk pengiriman email jika tidak ditentukan secara eksplisit.
SMTP_HOSTNAMEHostname mail server. Biasanya akan muncul sebagai nilai HELO/EHLO.
SMTP_USERUser SMTP yang akan digunakan untuk autentikasi.
SMTP_PASSWORD_FILELokasi file password SMTP di dalam container.
SMTP_TLS_CERT_FILELokasi file SSL certificate di dalam container.
SMTP_TLS_KEY_FILELokasi private key SSL di dalam container.
SMTP_MYNETWORKSNetwork yang diizinkan oleh Postfix.
SMTP_MESSAGE_SIZE_LIMITBatas maksimal ukuran email dalam byte.
VariableKeterangan
DKIM_ENABLEDMengaktifkan atau menonaktifkan DKIM signing. Gunakan true untuk mengaktifkan.
DKIM_DOMAINDomain yang digunakan untuk DKIM signing.
DKIM_SELECTORSelector DKIM yang digunakan. Contoh: default.
DKIM_PRIVATE_KEY_FILELokasi private key DKIM di dalam container.

Menjalankan Container

Setelah file docker-compose.yml selesai dibuat, jalankan container dengan command berikut:

docker compose up -d

Cek apakah container sudah berjalan:

docker ps

Untuk melihat log container:

docker logs -f ghost-smtp-relay

Jika tidak ada error, maka container SMTP relay sudah siap digunakan.

Penggunaan pada Aplikasi

SMTP relay ini bisa digunakan oleh aplikasi apa pun yang mendukung SMTP submission dengan STARTTLS dan SMTP AUTH.

Contoh aplikasi yang bisa menggunakan SMTP relay ini antara lain:

  • Ghost
  • WordPress
  • Laravel
  • Django
  • Grafana
  • aplikasi internal lainnya

Secara umum, konfigurasi SMTP pada aplikasi bisa diarahkan ke server tempat container ini berjalan.

Contoh konfigurasi SMTP:

SMTP Host     : mail.dotko.id
SMTP Port     : 587
SMTP Security : STARTTLS
SMTP Username : noreply@dotko.id
SMTP Password : sesuai isi file secrets/smtp_password

Catatan Penting

Ada beberapa hal yang perlu diperhatikan dari SMTP relay ini:

  • Aplikasi client hanya perlu mengirim email keluar melalui port 587.
  • Container ini tidak ditujukan sebagai mailbox server.
  • Container ini tidak menerima inbound email publik melalui port 25 secara default.
  • Dovecot hanya digunakan sebagai backend SASL authentication, bukan sebagai server IMAP/POP3.
  • OpenDKIM hanya aktif jika DKIM_ENABLED=true.
  • Saat ini satu akun SMTP runtime didukung melalui SMTP_USER dan SMTP_PASSWORD_FILE atau SMTP_PASSWORD.

Dengan setup ini, aplikasi seperti Ghost bisa mengirim email secara lebih rapi menggunakan SMTP relay sendiri, tanpa perlu bergantung pada akun email pribadi sebagai sender.

Selain terlihat lebih profesional, setup seperti ini juga lebih fleksibel karena bisa digunakan ulang untuk beberapa aplikasi lain yang membutuhkan pengiriman email keluar.