Category: IT

  • Catatan Carbonio: Restore Akun

    Catatan Carbonio: Restore Akun

    Backup tidak ada gunanya kalau kita tidak paham cara mengembalikannya. Di Carbonio, hampir semua operasi restore dilakukan lewat CLI, dan fiturnya cuma ada di versi berlisensi, bukan Community Edition. Tulisan ini saya ringkas dari dokumentasi resmi Zextras plus beberapa hal yang saya temui sendiri waktu praktik restore dan migrasi di lab sertifikasi.

    Sebelum restore, pastikan dulu

    • Modul backup harus aktif dengan urutan yang benar: lisensi aktif, start service module, baru doSmartScan start. Tanpa ini, operasi restore tidak akan jalan.
    • SmartScan harus dalam keadaan jalan. Kalau mati, restore apa pun akan gagal.
    • Item baru ditandai sebagai deleted setelah dihapus dari mailbox melalui operasi Purge. Selama belum di-purge, item masih tersedia untuk dipulihkan.

    Pilihan strategi restore

    Ada beberapa strategi, dan masing-masing punya kegunaannya sendiri:

    • doItemRestore untuk mengembalikan satu item tertentu ke sebuah mailbox berdasarkan itemID. Bisa juga dikembalikan ke folder yang berbeda dari aslinya.
    carbonio backup doItemRestore john@example.com 4784
    • doUndelete alias Time-range Undelete, untuk memulihkan item dalam satu titik atau rentang waktu tertentu, termasuk status item pada saat itu. Carbonio otomatis mengirim email ke pemicu restore dan admin di awal dan akhir proses.
    carbonio backup doUndelete ...
    • doRestoreOnNewAccount untuk mengembalikan isi sebuah akun ke akun baru, cocok kalau kita tidak mau menimpa akun yang sudah ada. Setelah selesai, konfigurasi mailbox baru bisa dicek dengan carbonio config dump.
    • doExternalRestore untuk mengimpor backup dari infrastruktur yang berbeda. Ini pilihan untuk migrasi akun atau seluruh domain, membangun environment testing, sampai disaster recovery. Ini satu-satunya strategi yang server sumber dan tujuannya boleh beda, dan selain data, share milik akun ikut dikembalikan. Begitu dijalankan, domain dan akun langsung dibuat sehingga user bisa langsung kirim dan terima email walau item lama masih dipulihkan.
    carbonio backup doExternalRestore /path/to/the/old/store

    Restore Account adalah satu-satunya yang lewat GUI, ada di Admin Panel, Domains, Manage, Restore Account. Sisanya semua via CLI.

    Disaster recovery singkat

    Untuk pemulihan penuh setelah hardware atau infrastruktur rusak, alurnya: install Carbonio di server baru, atur Server dan Global settings, mount folder backup server lama (atau pakai backup eksternal terakhir kalau tidak tersedia), lalu jalankan doExternalRestore dengan Backup Path lama sebagai sumber. Kalau pulih dari snapshot VM, pastikan Backup Path tidak ikut di-rollback supaya datanya tetap ada untuk diimpor.

    Tips

    Beberapa hal di bawah ini yang sempat bikin saya tersendat waktu praktik external restore:

    1. doExternalRestore tidak mem-provision akun apa pun kalau SmartScan belum diinisialisasi. Jalankan doSmartScan start dulu, baru restore.
    2. doSmartScan butuh argumen start. Kalau cuma ketik doSmartScan, tidak jalan.
    3. Lisensi NFR belum aktif bikin error module ZxBackup is disabled. Aktifkan lisensi dan start service module dulu sebelum apa-apa.
    4. Saat External Restore banyak domain, stop dulu service backup-realtime, baru aktifkan lagi dan jalankan SmartScan setelah selesai, supaya beban server tidak melonjak. Nama service-nya backup-realtime, bukan RealTimeScanner.
    5. Log restore yang valid bukan output terminal. Output terminal cuma berisi operationId. File log yang benar ada di /opt/zextras/log/op_ExternalRestore_<uuid>.log. Saya pernah kehilangan poin di submission gara-gara salah ambil ini.
    6. Migrasi Files (Drive) dilakukan terpisah setelah restore email. Cari map file dengan ls /opt/zextras/backup/zextras/map_*, lalu jalankan carbonio-drive-migration -b <path_backup> -m /opt/zextras/backup/zextras/map_<uuid> -t https://hostname/. Flag -t itu URL server Carbonio, bukan domain yang diimpor, dan default-nya sudah ke hostname jadi bisa dihilangkan.
    7. Selalu validasi setelah restore. Waktu praktik, saya cek email masuk, recurring calendar event, kontak, dan signature memang ikut termigrasi dengan utuh, jadi tidak cuma mengandalkan pesan sukses di terminal.

    Penutup

    Kuncinya, pilih strategi restore sesuai kebutuhan: item tunggal pakai doItemRestore, item terhapus pakai doUndelete, dan migrasi atau disaster recovery pakai doExternalRestore. Tapi semua itu cuma jalan kalau modul backup diaktifkan dengan urutan yang benar dan SmartScan menyala. Detail di sini saya ambil dari dokumentasi resmi dan praktik di lab, jadi tetap cek dokumentasi versi yang kalian pakai karena perintah dan default bisa berubah antar rilis.

  • Ceph di Proxmox Lambat? 10 Pengecekan untuk Menemukan Sumber Masalahnya

    Ceph di Proxmox Lambat? 10 Pengecekan untuk Menemukan Sumber Masalahnya

    Hari ini saya membaca cara pengecekan jika Ceph lambat dari artikel cr0x.net (sumber di akhir tulisan), kemudian dari bacaan tersebut saya jadikan tulisan ini dan saya rangkum dan ringkas dan fokus ke sepuluh pengecekannya saja.

    Ceph di Proxmox sering jalan mulus sampai kalian migrasi VM atau mulai backup, lalu tiba-tiba latency naik dan iowait melonjak. Penyebabnya jarang misterius, biasanya cuma salah satu dari sepuluh hal yang bisa diukur: jaringan, recovery, disk class yang ketukar, metadata BlueStore, CPU, atau CRUSH rule.

    Prinsip utamanya, sebelum tuning apa pun, buktikan dulu bottleneck-nya ada di jaringan, media OSD, atau recovery. Tuning di layer yang salah cuma memperparah.

    Check 1: Kesehatan cluster dan slow ops

    Cek dulu apakah cluster sedang rebuild, karena recovery bisa menurunkan performa secara wajar.

    ceph -s
    ceph health detail

    Di detail slow ops, “waiting for subops” mengarah ke jaringan atau replikasi, sedangkan “waiting for BlueStore kv commit” mengarah ke DB/WAL atau disk.

    Check 2: Pastikan masalahnya di Ceph

    Pastikan VM yang lambat memang ada di RBD, bukan di storage lokal.

    pvesm status
    rbd -p ceph-vm ls | head

    Kalau cuma sebagian workload di Ceph, bandingkan dengan storage lain dulu. Kalau rbd ls saja lambat, curigai MON/MGR atau jaringan.

    Check 3: Jaringan, drops, dan MTU

    Jaringan adalah bus storage Ceph, jadi cek drops, retransmit, dan konsistensi MTU.

    ip -s link show dev eno2
    ping -c 5 -M do -s 8972 10.10.10.12
    ss -ti dst 10.10.10.12 | head

    RX drops tinggi dan retransmit yang naik saat beban adalah tanda jaringan, bukan tanda perlu tuning BlueStore. Kalau ping -M do gagal atau ada loss, berarti MTU tidak konsisten antar NIC, bond, bridge, dan switch.

    Check 4: Public vs cluster network

    Pastikan trafik replikasi tidak berebut jalur dengan trafik klien.

    ceph config get mon public_network
    ceph config get mon cluster_network

    Kalau cluster_network kosong, recovery dan replikasi berbagi jaringan dengan klien. Pisahkan kalau kalian punya NIC atau VLAN terpisah.

    Check 5: Overhead replikasi atau EC

    Setiap write di pool size 3 jadi tiga write. Erasure coding hemat kapasitas tapi berat untuk write kecil.

    ceph osd pool ls detail
    ceph tell osd.* perf dump | head -n 20

    Untuk VM dengan write random kecil, replikasi biasanya pilihan paling masuk akal. Kalau subop_latency naik relatif terhadap op_latency, curigai jaringan atau ada OSD peer yang lambat.

    Check 6: Disk class dan CRUSH rule

    Jangan biarkan OSD HDD nyelinap ke pool yang seharusnya full SSD.

    ceph osd tree
    ceph osd crush rule dump replicated_rule

    Cek kolom CLASS di osd tree. Kalau rule tidak menyaring device class, HDD bisa terpilih jadi replika di pool SSD. Solusinya buat rule berbasis class.

    Check 7: Penempatan DB/WAL BlueStore

    OSD SSD pun bisa lambat kalau metadata (DB/WAL) ditaruh di media yang salah.

    ceph-volume lvm list
    ceph daemon osd.3 perf dump

    lvm list menunjukkan DB/WAL tiap OSD ada di device mana, idealnya DB/WAL OSD HDD ada di SSD atau NVMe. Di perf dump, lihat bagian bluestore. Latency kv commit yang tinggi (puluhan sampai ratusan ms) berarti device DB jenuh atau terlalu banyak OSD numpuk di satu DB.

    Check 8: CPU, memori, dan scheduler OSD

    OSD juga butuh CPU untuk checksum dan jaringan, terutama di node hyperconverged.

    ceph daemon osd.3 dump_historic_ops
    top -b -n 1 | head -n 15
    cat /sys/block/sdb/queue/scheduler

    Operasi lebih dari satu detik tidak normal untuk SSD yang sehat. Korelasikan dengan load average, iowait, dan CPU steal. mq-deadline wajar untuk SSD, none wajar untuk NVMe.

    Check 9: Recovery, backfill, dan scrub

    Kerja latar belakang Ceph rebutan disk dan jaringan dengan klien, dan bisa aktif meski status HEALTH_OK.

    ceph config get osd osd_recovery_max_active
    ceph config get osd osd_max_backfills
    ceph config set osd osd_recovery_sleep 0.1

    Nilai lebih tinggi berarti recovery cepat tapi latency klien buruk, nilai lebih rendah sebaliknya. Untuk cluster kecil, jaga tetap konservatif saat jam sibuk dan kembalikan setelah insiden.

    Check 10: Benchmark yang benar

    Benchmark berguna kalau menjawab pertanyaan spesifik, bukan sekadar “seberapa cepat Ceph”.

    rados bench -p ceph-vm 30 write --no-cleanup
    rbd perf image iostat --pool ceph-vm --image vm-100-disk-0 --interval 2 --count 5

    rados bench jelek berarti masalah di sisi cluster (jaringan, OSD, recovery). rados bench bagus tapi VM tetap lambat berarti masalah di sisi klien (setting RBD, pola IO). Bersihkan sisa benchmark dengan rados -p ceph-vm cleanup.

    Penutup

    Urutannya: tangkap kondisi saat lambat (ceph -s, ceph health detail, drops NIC, tes MTU, retransmit), pastikan rule pool tidak mencampur disk class dan network sudah terpisah, lalu perbaiki strukturnya (DB/WAL ke device yang benar, keluarkan disk outlier, atasi oversubscription). Tuning dilakukan paling akhir.

    Sumber: cr0x.net, “Ceph performance on Proxmox is slow: 10 checks that actually find the bottleneck” (https://cr0x.net/en/proxmox-ceph-slow-performance-checks/).

  • Bikin Daily To-Do Dashboard (TUI) Pakai Go dan Gemini CLI

    Bikin Daily To-Do Dashboard (TUI) Pakai Go dan Gemini CLI

    Latar belakang

    Sehari-hari kegiatan saya itu ada di terminal. SSH ke server, ngoprek infrastruktur, sampai belajar hal-hal baru semuanya saya lakukan dari command line. Tapi ada satu kebiasaan yang lama-lama terasa mengganggu: tiap kali mau tahu tugas berikutnya apa, saya harus keluar dulu dari terminal, buka browser, buka Notion atau catatan, baru balik lagi ngetik. Kelihatannya sepele, tapi pindah-pindah konteks seperti ini diam-diam memecah fokus.

    Dari situ muncul pikiran sederhana: kenapa daftar tugas harian saya nggak sekalian saya taruh di terminal saja, di tempat yang sama dengan saya kerja? Daripada bolak-balik ke Notion, mending semuanya ada di satu layar. Akhirnya saya coba bikin sendiri, dan jadilah project kecil ini: sebuah Daily To-Do Dashboard berbasis TUI.

    Apa itu TUI

    TUI itu singkatan dari Terminal User Interface. Bedanya dengan CLI biasa, kalau CLI umumnya sekali jalan langsung keluar output teks yang statis, TUI adalah aplikasi interaktif yang “hidup” di dalam terminal. Ada layout, navigasi pakai keyboard, warna, dan tampilan yang bisa berubah secara real-time, tapi semuanya tetap berjalan di emulator terminal tanpa perlu GUI.

    Kemungkinan besar kalian sudah sering pakai TUI tanpa sadar. Beberapa contoh yang biasa saya pakai sehari-hari: htop atau btop buat monitoring sistem, lazygit buat ngurus git, k9s buat Kubernetes, dan ncdu buat lihat pemakaian disk. Buat orang yang memang tinggal di terminal, TUI ini enak banget. Tangan nggak perlu lepas dari keyboard, aplikasinya ringan, dan yang paling penting tetap jalan walau cuma diakses lewat SSH ke server yang nggak punya tampilan desktop.

    Gemini CLI: alasan dan instalasi singkat

    Untuk membangun project ini saya pakai bantuan AI coding agent langsung dari terminal. Sebenarnya pilihan pertama saya adalah Claude Code, tapi Claude Code tidak tersedia di paket gratis. Untuk memakainya minimal harus langganan Pro atau pakai kredit API. Akun API baru memang dapat sedikit kredit gratis untuk coba-coba, tapi nggak cukup buat dipakai terus-menerus. Karena waktu itu saya cuma mau eksperimen dulu, saya cari opsi yang bisa gratis di awal, dan Gemini CLI jadi jawabannya.

    Gemini CLI adalah AI agent open-source dari Google yang jalan langsung di terminal dan punya free tier yang cukup untuk kebutuhan ngoprek harian. Cara installnya gampang. Prasyaratnya cuma Node.js (disarankan versi LTS, minimal Node 18). Setelah itu tinggal jalankan:

    npm install -g @google/gemini-cli

    Lalu untuk memulainya cukup ketik:

    gemini

    Kalau kalian cuma ingin mencoba tanpa install permanen, bisa langsung pakai npx:

    npx @google/gemini-cli

    Saat pertama kali dijalankan, kalian akan diminta autentikasi. Paling gampang login pakai akun Google untuk free tier, atau pakai API key kalau memang butuh.

    Satu catatan penting yang perlu diketahui. Per 18 Juni 2026, Google menghentikan layanan Gemini CLI untuk pengguna free tier, Google AI Pro, dan Ultra, lalu mengarahkan penggunanya ke tool baru bernama Antigravity CLI. Jadi kalau kalian membaca tulisan ini setelah tanggal tersebut dan memakai akun gratis, perintah gemini kemungkinan sudah tidak melayani request lagi. Saya sendiri membangun project ini selagi free tier-nya masih aktif. Buat yang baru mulai sekarang, silakan cek Antigravity CLI sebagai penerusnya, atau pertimbangkan opsi lain seperti Claude Code kalau sudah siap berlangganan.

    Struktur folder dan generate README

    Project ini ditulis pakai Go, dengan ekosistem Charm sebagai fondasinya. Bubble Tea dipakai sebagai kerangka TUI-nya, Lipgloss untuk styling seperti warna, border, dan layout, lalu Bubbles untuk komponen siap pakai seperti text input, progress bar, dan help. Untuk penyimpanan datanya saya pakai SQLite lewat go-sqlite3, jadi task tetap tersimpan walau aplikasinya ditutup. Database-nya disimpan di ~/.todo-dashboard/tasks.db.

    Struktur foldernya dibuat modular mengikuti pola Model-View-Update (MVU), pola khas Bubble Tea yang terinspirasi dari Elm:

    .
    ├── main.go              # entry point: siapkan path DB, lalu jalankan program
    ├── internal/
    │   ├── db/db.go         # layer SQLite: add, get, toggle, delete task
    │   ├── models/task.go   # struct Task dan tipe Priority
    │   └── tui/model.go     # logika Bubble Tea: Model, Update, View, keymap, style
    ├── go.mod
    ├── go.sum
    └── .gitignore

    Inti dari pola MVU ini begini. Semua state aplikasi, mulai dari daftar task, posisi kursor, sampai mode input, disimpan di dalam Model. Setiap kejadian, entah itu tombol ditekan atau timer detik yang berdetak untuk update jam, masuk ke fungsi Update yang bertugas mengubah state. Lalu View merender tampilan dari state terbaru tadi. Alurnya jadi rapi dan gampang ditebak. Logika seperti navigasi kursor (j/k), menandai selesai (space), menambah task baru (n), dan menghapus (x) semuanya ada di model.go.

    Nah, untuk README.md saya minta tolong Gemini CLI yang menyusun. Hasilnya cepat dan rapi sebagai titik awal. Sudah ada bagian fitur, tech stack, cara install, tabel keybinding, sampai struktur project. Tapi saya mau jujur, README hasil generate tetap perlu dibersihkan manual. Punya saya misalnya masih menyisakan placeholder seperti URL clone yang masih bertuliskan yourusername dan gambar preview placeholder yang belum saya ganti dengan screenshot asli. Jadi menurut saya AI agent ini bagus banget untuk draft awal dan biar ngebut, tapi review manusia tetap wajib supaya dokumentasinya benar-benar cocok dengan repo. Buat kalian yang mau coba langsung, repo aslinya bisa dijalankan seperti ini:

    git clone https://github.com/rafiharli/todo-tui-dashboard.git
    cd todo-tui-dashboard
    go mod tidy
    go run main.go

    Menambah Task (tekan n)

    Menambah deadline (opsional)

    Input tanggal tidak sesuai format

    Hal kecil yang mempermudah

    Buat saya, project ini memang kecil dan sederhana, tapi justru di situ nilainya. Dia menyelesaikan satu gangguan kecil yang sering saya alami, yaitu nggak perlu lagi pindah-pindah ke notes atau app lain cuma untuk lihat tugas berikutnya. Sekarang daftar tugas harian ada di tempat yang sama dengan saya kerja, yaitu di terminal, dan itu saja sudah cukup bikin alur kerja saya terasa lebih ringan. Kebetulan sambil bikin ini saya juga belajar dasar-dasar Go, cara kerja TUI dengan Bubble Tea, dan bagaimana memanfaatkan AI agent di terminal tanpa menyerahkan semuanya bulat-bulat ke AI.

    Hal-hal kecil seperti ini menurut saya sering diremehkan, padahal kalau diakumulasi setiap hari dampaknya nyata. Nggak harus bikin aplikasi besar atau fitur yang rumit. Kadang yang kita butuhkan cuma satu tool sederhana yang menghapus satu langkah ekstra dari rutinitas. Kalau kalian juga sering di terminal dan punya kebiasaan kecil yang berulang-ulang dan agak mengganggu, coba pikirkan apakah bisa dipermudah dengan tool kecil buatan sendiri. Nggak harus sempurna, yang penting bisa menghemat sedikit waktu dan tenaga kalian. Buat saya, hal kecil yang mempermudah seperti ini justru yang paling kepakai sehari-hari.

    Beginner Tips:

    • Gunakan plan mode, agent, dan skill sebelum mengimplementasikan project. Ini berlaku pada platform AI manapun (claude code/gemini cli/codex cli).
  • Ceph vs ZFS untuk Proxmox 3 Nodes: Storage Decision

    Ceph vs ZFS untuk Proxmox 3 Nodes: Storage Decision

    Saya sedang merancang skenario implementasi Proxmox 3 node, dan tulisan ini saya jadikan dasar buat memutuskan mau pakai storage mana. Pemilihan antara Ceph atau ZFS itu bukan tentang fiturnya lebih banyak, tapi soal mode failure mana yang sanggup ditangani waktu ada node yang mati/error.

    Skenario

    • Cluster Proxmox VE 3 node. Proxmox dengan 3 node ini jumlah minimum yang sehat buat quorum sekaligus titik masuk paling pas buat Ceph.
    • Targetnya storage yang andal buat disk VM, dengan jalur naik ke HA kalau nanti dibutuhkan.
    • Tiga hal yang harus saya tentukan sendiri sebelum memutuskan: butuh HA atau nggak, network-nya seberapa kencang, dan workload-nya seperti apa.

    Pertanyaan kunci

    Biasanya cukup jawab satu pertanyaan ini:

    • Apakah dibutuhkan HA? Maksudnya node mati tapi VM tetap jalan tanpa ada yang sadar.
      • Kalau ya dan network mendukung: ambil Ceph (RBD).
      • Kalau failover beberapa menit masih oke dan tinggal restore dari backup: ZFS lokal + replikasi jadi jawaban.

    Dua opsi di 3 node

    Opsi A: Ceph (RBD)

    • Cocok jika membutuhkan shared storage dan HA langsung dari Proxmox.
    • Kelebihan: node mati, disk VM tetap kebaca; cluster nyembuhin diri sendiri; live migration mulus tanpa pindah-pindah disk.
    • Kekurangan: operasionalnya lebih rumit, dan berkaitan sama network.
    • Kebutuhan: network minimal 10GbE terpisah (idealnya 25GbE), OSD seragam (SSD/NVMe), replikasi size 3, failure domain per host.

    Opsi B: ZFS lokal + replikasi

    • Cocok kalau network terbatas, tim kecil, atau memakai model restore-based.
    • Kelebihan: simpel, latency rendah (apalagi pakai mirror), hardware lebih murah, integritas data juara.
    • Kelemahan: nggak ada shared storage bawaan; ada jeda data karena replikasi sifatnya async; failover-nya hitungan menit.
    • Kebutuhan: mirror buat disk VM, replikasi (zfs send/receive) ke node lain, plus Proxmox Backup Server.

    Perbandingan cepat

    AspekCeph (RBD)ZFS lokal + replikasi
    HA / shared storage bawaanYaTidak
    Saat node matiVM tetap jalanFailover atau restore beberapa menit
    Network25GbE ideal, minimal 10GbE terpisah10GbE cukup, 1GbE pun bisa
    Kompleksitas operasionalTinggiRendah
    DiskOSD seragam SSD/NVMeMirror SSD/NVMe
    Risiko data saat node matiMinim (size 3)Ada jeda replikasi
    Paling cocokTrue HA, banyak VMSimpel, network terbatas

    Keputusan

    Buat skenario 3 node ini, kalau memang tujuannya High Availability dan syarat network terpenuhi, saya pilih Ceph (RBD) dengan size 3 dan failure domain per host. Tiga node itu pas banget buat Ceph: tiga MON buat quorum, dan persis satu salinan data per host.

    Perintah buat ngecek kondisi

    • pvesm status: lihat storage apa aja yang kebaca Proxmox dan udah kepakai berapa persen. Jaga Ceph tetap di bawah 75 sampai 80 persen.
    • zpool status -x: cek kesehatan ZFS. Kalau jawabannya bukan “all pools are healthy”, beresin dulu sebelum lanjut.
    • ceph -s: lihat health cluster sekilas. HEALTH_WARN dengan slow ops yang nggak ilang-ilang itu udah masuk kategori insiden produksi.
    • ceph osd perf: cari OSD yang lambat sendirian, soalnya satu OSD aja bisa narik turun latency seluruh cluster.
    • ceph osd pool ls detail: pastiin size-nya 3, bukan 2.

    Sumber

  • Konfigurasi Fitur Zimbra: Forwarding, Reply-To, dan Mail Filter

    Konfigurasi Fitur Zimbra: Forwarding, Reply-To, dan Mail Filter

    Zimbra menyediakan berbagai fitur pengaturan email yang bisa dilakukan melalui GUI maupun command line (CLI). Tiga fitur yang paling sering digunakan dalam administrasi email adalah forwarding, reply-to, dan mail filter. Ketiganya berperan penting dalam mengatur alur distribusi email, pengelolaan respons, serta otomatisasi pemrosesan pesan.


    1. Konsep Dasar Email Management di Zimbra

    Sebelum masuk ke perintah, penting memahami bahwa Zimbra menyimpan semua konfigurasi user di LDAP. Setiap perubahan yang dilakukan melalui CLI seperti zmprov atau zmmailbox akan langsung tersinkronisasi dengan mailbox server.

    Secara umum:

    • Forwarding → meneruskan email ke alamat lain
    • Reply-To → menentukan alamat balasan
    • Filter → aturan otomatis untuk memproses email masuk

    2. Email Forwarding (Penerusan Email)

    Forwarding digunakan ketika email yang masuk ke satu user ingin diteruskan ke alamat lain secara otomatis.

    Perintah CLI

    zmprov ma user1@domain.com zimbraPrefMailForwardingAddress target@gmail.com

    Jika ingin mengaktifkan tanpa menyimpan copy lokal:

    zmprov ma user1@domain.com zimbraPrefMailLocalDeliveryDisabled TRUE

    Fungsi utama

    • Backup email ke external
    • Migrasi email sementara
    • Monitoring mailbox

    3. Reply-To Address

    Reply-To digunakan untuk mengarahkan balasan email ke alamat yang berbeda dari pengirim asli.

    Perintah CLI

    zmprov ma user1@domain.com \
    zimbraPrefReplyToEnabled TRUE \
    zimbraPrefReplyToAddress helpdesk@domain.com

    Fungsi utama

    • Masking alamat asli user
    • Centralized response handling

    4. Mail Filter (Rule Otomatis Email)

    Filter digunakan untuk mengatur bagaimana email diproses secara otomatis berdasarkan kondisi tertentu.

    Contoh via CLI

    zmprov ma "user${i}@zimbra.server" zimbraMailSieveScript '# gmail-filter
    if anyof (header :contains "from" "gmail.com") {
        fileinto "Test";
        stop;
    }'

    Fungsi utama

    • Auto sorting email
    • Anti spam sederhana
    • Workflow automation
    • Routing email ke folder tertentu

    5. Folder Target Filter

    Sebelum filter digunakan, folder harus dibuat:

    zmmailbox -z -m user1@domain.com createFolder /Inbox/Test

    Best Practice

    Dalam environment production, ada beberapa best practice:

    • Gunakan CLI untuk mass configuration
    • Hindari editing manual database LDAP
    • Pastikan folder filter sudah ada sebelum rule dibuat
    • Audit forwarding secara rutin
    • Batasi external forwarding untuk keamanan

    Penutup

    Forwarding, Reply-To, dan Filter adalah tiga komponen penting dalam manajemen email Zimbra:

    • Forwarding → mengalihkan email
    • Reply-To → mengatur arah balasan
    • Filter → otomatisasi pemrosesan email

    Dengan memahami ketiganya, administrator dapat mengelola sistem email dengan lebih efisien, aman, dan terstruktur.

  • Struktur File Ansible untuk Instalasi Zimbra Single Server

    Struktur File Ansible untuk Instalasi Zimbra Single Server

    Beberapa waktu terakhir saya iseng oprek oprek menyusun ulang project Ansible saya untuk instalasi Zimbra single server. Alasannya sederhana, dulu saya buat struktur seadanya, satu playbook panjang, variabel campur aduk, dan ujungnya susah dipakai ulang. Jadi di postingan ini saya bagikan bagaimana saya menata file dan folder Ansible untuk instalasi Zimbra single server, lengkap dengan alasan kenapa tiap bagian saya pisah seperti itu.

    Postingan ini fokus pada strukturnya saja, bukan isi task detail per file. Kalau ada bagian yang mau saya dalami di tulisan terpisah, silakan kasih tahu saya di komentar.

    Gambaran umum

    Begini struktur akhir yang saya pakai sekarang.

    tree zimbra-ansible

    Output tree zimbra-ansible/ di terminal saya jadikan screenshot pertama, biar pembaca punya gambaran utuh sebelum saya bahas tiap bagian.

    ansible.cfg

    File ansible.cfg di root project saya pakai untuk override default Ansible khusus project ini, jadi tidak perlu menyentuh konfigurasi global di /etc/ansible/ansible.cfg. Isinya kira-kira soal lokasi inventory, path role, retry files yang saya matikan, dan beberapa setting koneksi SSH seperti host_key_checking = False saat lab.

    Manfaat utama menempatkan ansible.cfg di project, ketika ada anggota tim lain yang clone repository, mereka langsung dapat konfigurasi yang sama tanpa perlu setup global. Praktik komunitas memang menyarankan project-level config untuk repository yang akan dibagi.

    Inventory dan group_vars

    Folder inventory/ di project saya isinya hanya hosts.ini. File ini berisi daftar host beserta pengelompokannya. Untuk Zimbra single server isinya simpel, hanya satu host di bawah grup zimbra_servers. Walaupun cuma satu mesin, saya tetap pakai grup karena memudahkan kalau suatu hari struktur berkembang ke multi-server.

    Folder group_vars/ saya letakkan di root project, bukan di dalam inventory/. Ansible mendukung dua pola ini, dan saya pilih yang di root karena lebih mudah dilihat dan diedit. File all.yml di dalamnya menyimpan variabel yang berlaku untuk semua host, misalnya zimbra_version, zimbra_domain, zimbra_admin_email, timezone, dan URL download installer.

    Untuk skala single server, satu file all.yml sudah cukup. Kalau nanti host bertambah dan tiap grup butuh variabel berbeda, tinggal saya tambah file seperti group_vars/zimbra_servers.yml. Begitu pula host_vars/ belum saya buat karena belum perlu, tapi sudah siap saya tambahkan ketika ada host yang butuh override individual.

    site.yml

    File site.yml di root saya pakai sebagai entry point utama playbook. Isinya menarget grup zimbra_servers dan memanggil role zimbra_single. Di sini saya juga set become: true dan gather_facts: true, ditambah beberapa pre_tasks ringan seperti update cache paket atau memastikan Python tersedia di target.

    Untuk project sekecil ini saya belum pecah site.yml ke beberapa playbook di folder playbooks/. Kalau besok saya tambah role lain misalnya monitoring atau backup, baru saya pisah jadi playbooks/zimbra.yml, playbooks/monitoring.yml, lalu site.yml saya jadikan orchestrator yang berisi import_playbook saja.

    Role zimbra_single

    Bagian paling besar adalah role itu sendiri. Saya namai zimbra_single karena memang khusus untuk topologi single server. Nantinya kalau saya bikin multi-server, saya buat role terpisah seperti zimbra_mta atau zimbra_proxy agar tanggung jawab masing-masing role jelas, ketimbang memaksa satu role besar mengakomodasi semuanya dengan logika percabangan yang ribet.

    defaults dan vars

    Saya isi defaults/main.yml dengan variabel yang user role boleh ubah, misalnya path download installer, nama user dan grup Zimbra, dan daftar komponen yang diinstall. Sifatnya nilai default, prioritas paling rendah, jadi mudah di-override dari group_vars atau host_vars.

    Folder vars/ saya sengaja biarkan kosong untuk sekarang. Bedanya dengan defaults, isi vars/main.yml itu prioritasnya tinggi dan susah di-override tanpa sengaja. Saya rencanakan untuk konstanta internal role yang tidak boleh diutak-atik user, misalnya nama service Zimbra atau path binary zmcontrol. Karena belum ada kebutuhan konkret, saya biarkan dulu agar tidak menambah noise.

    tasks

    Folder tasks/ adalah jantung role. File main.yml saya buat tipis, isinya hanya include_tasks ke file-file lain berdasarkan urutan eksekusi. Pemecahan ini disengaja agar tiap file punya tanggung jawab tunggal dan mudah dibaca.

    File preflight.yml melakukan pengecekan awal sebelum instalasi dimulai. Cek RAM minimum, free disk space, versi OS yang didukung, dan resolusi DNS hostname. Kalau salah satu gagal, playbook stop di sini sebelum sempat merusak apa-apa. Ini investasi waktu yang worth it karena Zimbra cukup picky soal prasyarat.

    File os_debian.yml dan os_redhat.yml saya pecah berdasarkan OS family. Isinya menangani persiapan OS yang spesifik per distro, mulai dari instalasi paket dependensi, disable service yang bentrok seperti postfix atau sendmail bawaan, sampai konfigurasi firewall (UFW untuk Debian, firewalld untuk RHEL). Saya pilih pendekatan pecah file per OS ketimbang satu file panjang dengan when: ansible_os_family == "...", karena lebih bersih saat dibaca dan lebih mudah dirawat kalau salah satu distro butuh logika kompleks. Pemanggilannya tetap pakai when di main.yml, jadi hanya satu file yang dijalankan tergantung OS target.

    File download.yml mengunduh tarball installer Zimbra dari URL yang didefinisikan di variabel, lalu mengekstraknya ke direktori kerja. Saya tambahkan verifikasi checksum SHA256 di sini untuk memastikan file tidak korup atau diganti di tengah jalan.

    File install.yml menjalankan installer dalam mode unattended menggunakan config file. Ini bagian paling tricky karena installer Zimbra interaktif by default. Saya pakai template zinstall.cfg.j2 untuk menghasilkan config file yang dibaca oleh install.sh -s -c. Nilai yang ditemplate antara lain admin password, domain, time zone, hostname, dan komponen yang dipilih.

    File config.yml berisi konfigurasi setelah instalasi selesai. Set admin password lewat zmprov, atur quota default, konfigurasi domain dan COS, restart service kalau perlu, dan hal-hal lain yang sifatnya tuning post-install. Saya konsolidasikan ke satu file karena task-nya saling terkait dan dijalankan beruntun. Kalau ke depan jumlahnya membengkak, baru saya pecah lagi misalnya jadi ssl.yml, quota.yml, dan seterusnya.

    handlers

    Folder handlers/main.yml menyimpan handler yang dipanggil pakai notify. Untuk Zimbra saya punya handler restart zimbra yang menjalankan zmcontrol restart sebagai user zimbra, dan reload firewall. Pemakaian handler ini menjaga idempotensi, restart hanya terjadi kalau memang ada perubahan, bukan setiap kali playbook dijalankan.

    templates

    File-file di templates/ berekstensi .j2 karena diproses Jinja2. Saya punya dua, hosts.j2 untuk men-generate /etc/hosts yang Zimbra-friendly (urutan baris dan FQDN harus benar, kalau tidak installer langsung gagal), dan zinstall.cfg.j2 untuk config file installer Zimbra yang dipakai mode unattended.

    Praktik yang saya ikuti, semua nilai yang berubah-ubah saya parameterkan lewat variabel, bukan hardcode di template. Misalnya {{ zimbra_admin_password }}, {{ zimbra_domain }}, {{ ansible_fqdn }}. Dengan begini template bisa dipakai ulang untuk berbagai environment tanpa harus diedit ulang.

    requirements.yml

    Di root project saya punya requirements.yml yang mendaftarkan collection eksternal yang dipakai role, misalnya community.general dan ansible.posix. Anggota tim lain yang clone repo cukup jalankan ansible-galaxy collection install -r requirements.yml dan dependency mereka beres.

    Praktik ini termasuk yang sering dilupakan tapi sangat penting. Tanpa requirements.yml, playbook bisa error karena modul tidak ketemu, dan debugging-nya menyebalkan, apalagi kalau yang menjalankan bukan kalian sendiri.

    Hal yang belum saya tambahkan

    Ada beberapa hal yang belum ada di struktur sekarang tapi sebenarnya layak dipertimbangkan ke depan.

    Pertama, Ansible Vault untuk menyimpan secret seperti password admin Zimbra dan password LDAP. Pola yang biasa dipakai, buat file group_vars/vault.yml yang dienkripsi pakai ansible-vault encrypt, lalu variabel di dalamnya diberi prefix vault_. Di file plaintext tinggal dibuat alias seperti zimbra_admin_password: "{{ vault_zimbra_admin_password }}". Untuk lab saya masih pakai variabel plaintext, tapi sebelum dipakai di environment yang lebih serius, vault wajib ditambahkan.

    Kedua, folder meta/ di dalam role yang berisi metadata seperti author, license, dan platform yang didukung. Kalau suatu hari role ini saya publish ke Ansible Galaxy atau saya share ke tim lain, file ini yang dibaca pertama kali. Tidak urgent untuk lab, tapi bagus dimiliki.

    Ketiga, README di dalam role itu sendiri. README di root sudah ada, tapi role yang reusable idealnya punya README sendiri yang mendokumentasikan variabel yang tersedia dan contoh pemakaian.

    Penutup

    Struktur di atas bukan satu-satunya cara, tapi cukup mewakili praktik yang umum dipakai komunitas Ansible. Inti yang saya pegang ada empat, pisahkan inventory dari role agar reusable, taruh variabel sesuai hierarki, pecah tasks per tanggung jawab, dan jangan pernah commit secret tanpa enkripsi.

    Kalau kalian baru mulai dengan Ansible, saran saya jangan langsung niru struktur lengkap. Mulai dari yang sederhana, satu playbook, satu inventory, satu role. Begitu kompleksitas naik, baru pelan-pelan pecah sesuai kebutuhan. Struktur yang baik itu yang menjawab masalah nyata, bukan struktur yang rapi tapi over-engineered untuk skala kecil.

    Kalau ada bagian yang ingin saya bahas lebih detail, misalnya isi zinstall.cfg.j2 lengkap atau task instalasi Zimbra step by step, kasih tahu saya di komentar.

  • Troubleshoot Zimbra: Email Tidak Terkirim Antar User Beda Mailbox

    Troubleshoot Zimbra: Email Tidak Terkirim Antar User Beda Mailbox

    Halo kembali lagi bersama Rafi. Tulisan kali ini saya buat sebagai catatan setelah saya selesai instalasi Zimbra dengan skema multi server di lab. Selesai instalasi, semua service kelihatannya aman, tidak ada error mencolok, login webmail juga lancar. Tapi begitu saya coba kirim email dari satu user ke user lain, email tidak pernah sampai ke inbox. Awalnya saya pikir mailbox yang bermasalah, ternyata jawabannya jauh lebih sepele, yaitu di resolv.conf. Berikut alur troubleshoot yang saya lakukan, semoga membantu kalian yang mengalami gejala serupa.

    Skema Lab Multi Server

    Sebelum masuk ke troubleshoot, saya cantumkan dulu skema lab yang saya pakai supaya kalian punya gambaran. Saya pisah role-nya per node:

    • ldap1.zimbra.server sebagai LDAP master dan DNS server
    • mbox1.zimbra.server sebagai mailbox node pertama
    • mbox2.zimbra.server sebagai mailbox node kedua
    • mta1.zimbra.server sebagai MTA+proxy node pertama
    • mta2.zimbra.server sebagai MTA+proxy node kedua

    User saya untuk uji coba ada dua, user1@zimbra.server yang mailbox-nya ada di mbox2, dan user2@zimbra.server yang mailbox-nya ada di mbox1.

    Periksa Log di MTA

    Saya login ke webmail sebagai user2@zimbra.server, lalu kirim email ke user1@zimbra.server. Di webmail terlihat email berhasil terkirim, tidak ada notifikasi error apapun di sisi pengirim. Tapi setelah saya cek inbox user1, email tidak ada.

    tail zimbra.log di mta2:

    su - zimbra
    tail -f /var/log/zimbra.log

    muncul

    Sampai sini saya pikir email lulus filter dan semua aman, namun akhirnyaaa…..

    Ketemu Error-nya

    Ternyata status email bounced:

    postfix/lmtp: 8EC8263EB4: to=<user1@zimbra.server>, relay=none,
      status=bounced (Host or domain name not found.
      Name service error for name=mbox2.zimbra.server type=A: Host not found)

    grep pesan bounced

    Ini menjelaskan kenapa email “terkirim” dari sisi user tapi tidak pernah sampai. MTA tahu mailbox tujuan ada di mbox2.zimbra.server, tapi MTA tidak bisa resolve A record dari hostname itu. Bahkan untuk balik mengirim notifikasi bounce ke user2, MTA juga gagal resolve mbox1.zimbra.server. Status code 5.4.4 di sini artinya “Unable to route”, yaitu murni masalah routing/DNS, bukan masalah autentikasi atau filter.

    Untuk memastikan, saya coba resolve manual dari mta2:

    [root@server ~]# getent hosts mbox2.zimbra.server
    [root@server ~]# dig +short mbox2.zimbra.server A

    dig Hasilnya kosong. Kemudian saya cek resolver-nya:

    [root@mta2 ~]# cat /etc/resolv.conf
    nameserver 127.0.0.1
    # Generated by NetworkManager
    search zimbra.server
    nameserver 192.168.14.80
    nameserver 8.8.8.8

    Dan inilah dia:

    nameserver 127.0.0.1

    Resolver di mta2 mengarah ke 127.0.0.1, padahal di node ini saya tidak menjalankan DNS server lokal. Setiap kali Postfix butuh resolve hostname mailbox, dia bertanya ke localhost, tidak ada yang jawab, jadi langsung gagal.

    Perbaikan resolv.conf

    Solusinya sederhana, saya arahkan resolver ke DNS server internal yang memang punya zona untuk zimbra.server. Saya edit /etc/resolv.conf:

    nameserver 192.168.14.80 #IP_ldap
    search zimbra.server

    Setelah itu saya tes ulang resolusi nama:

    [root@server ~]# getent hosts mbox1.zimbra.server
    192.168.14.81   mbox1.zimbra.server mbox1
    
    [root@server ~]# getent hosts mbox2.zimbra.server
    192.168.14.82   mbox2.zimbra.server mbox2

    Penutup

    Kasus ini sebenarnya simpel sekali, tapi gejalanya bisa bikin bingung karena di sisi user email kelihatan terkirim normal, dan log MTA juga menampilkan banyak baris “CLEAN” dan “Ok” sebelum akhirnya bounce. Pelajaran yang saya ambil, untuk deployment Zimbra multi server, DNS internal itu wajib hukumnya, dan resolv.conf di tiap node harus dicek satu per satu jangan sampai mengarah ke 127.0.0.1 kalau memang tidak ada DNS server lokal. Sebagai pengaman tambahan, isi juga /etc/hosts di semua node. Sekian dari saya, semoga catatan ini berguna kalau kalian mengalami hal yang sama.

  • Mengenal License Daemon Service (LDS) di Zimbra 10.1

    Mengenal License Daemon Service (LDS) di Zimbra 10.1

    Salah satu hal yang membuat saya cukup lama “linglung” waktu pertama kali memegang Zimbra 10.1 di lab adalah urusan lisensi. Hampir semua tutorial yang berserakan di internet menyebut soal file ZCSLicense.xml di /opt/zimbra/conf/, perintah zmlicense -i untuk install, dan konsep license daemon yang menempel di mailstore. Setelah saya cek langsung di server lab, semua referensi itu ternyata tidak lagi 100% benar. Zimbra 10.1 sudah memperkenalkan mekanisme lisensi yang baru, dan saya rasa ini topik yang perlu saya tulis supaya teman-teman tidak mengulangi kebingungan yang sama.

    Apa yang Berubah di Zimbra 10.1

    Zimbra 10.1 yang rilis pertengahan 2024 memperkenalkan service baru bernama License Daemon Service atau singkatnya LDS. Service ini adalah komponen wajib di Zimbra Network Edition, dan bertugas menjadi jembatan antara mailbox server kalian dengan server lisensi resmi Zimbra (license.zimbra.com).

    Yang lebih signifikan, format lisensinya juga berubah. Kalau dulu kalian terbiasa dengan file XML, sekarang lisensi online menggunakan kunci alfanumerik 18 sampai 26 karakter yang kalian aktivasi via perintah. File XML hanya masih digunakan untuk skenario offline activation, dengan flow yang berbeda dari sebelumnya.

    Konsep “license daemon menempel di mailstore” yang banyak ditemui di dokumentasi versi 8 dan 9 sudah tidak berlaku. LDS sekarang adalah service yang berdiri sendiri, dengan package terpisah bernama zimbra-license-daemon.

    Dimana LDS Sebaiknya Ditempatkan

    Inilah pertanyaan yang menurut saya paling sering bikin bingung waktu instalasi multi-server. Berdasarkan rekomendasi resmi Zimbra, ada tiga opsi penempatan, dengan urutan preferensi sebagai berikut.

    • Pilihan pertama dan paling direkomendasikan adalah node dedicated khusus untuk LDS. Ini cocok untuk environment produksi dengan banyak mailbox server. LDS adalah service yang ringan, tidak butuh resource besar, tapi memisahkannya membuat pengelolaan lebih bersih.
    • Pilihan kedua, kalau tidak memungkinkan punya node terpisah, LDS bisa ditempatkan di node Proxy atau MTA. Alasannya, dua node ini biasanya memang sudah punya jalur keluar ke internet karena posisinya di edge. Jadi tidak perlu membuka rute baru hanya untuk LDS.

    Yang penting untuk kalian ingat, LDS tidak direkomendasikan ditempatkan di mailstore. Ini perubahan mendasar dari konsep lama Zimbra. Mailstore biasanya berada di zona internal yang lebih tertutup, dan menambahkan kebutuhan internet di sana hanya untuk lisensi mencampur tanggung jawab yang sebenarnya bisa dipisah.

    Urutan Instalasi yang Benar di Multi-Server

    Karena LDS adalah prasyarat untuk mailbox server, urutan instalasi multi-server di Zimbra 10.1 menjadi:

    1. Install dan konfigurasi LDAP server
    2. Install LDS di node dedicated atau di Proxy/MTA
    3. Baru install mailbox server
    4. Lanjut ke MTA, Proxy, dan komponen lain

    Kalau kalian mencoba install mailbox dulu sebelum LDS, installer akan menolak dengan pesan yang cukup jelas: zimbra-license-daemon should be installed prior to zimbra-store. Saya pernah lupa urutannya dan akhirnya harus mengulang dari awal.

    Perintah Dasar yang Perlu Dikenal

    Ada dua keluarga perintah yang akan sering kalian pakai. Yang pertama untuk mengelola lisensinya sendiri, yang kedua untuk mengelola service LDS-nya.

    Untuk lisensi, gunakan zmlicense sebagai user zimbra:

    zmlicense -a <LICENSE-KEY>     # Aktivasi lisensi online (kunci alfanumerik)
    zmlicense -A /path/to/license.xml  # Aktivasi lisensi offline (file XML)
    zmlicense -p                    # Lihat detail lisensi
    zmlicense -c                    # Cek status lisensi
    zmlicense -rc                   # Refresh cache lisensi di mailbox

    Perhatikan perbedaan antara -a huruf kecil dan -A huruf besar. Yang kecil untuk online, yang besar untuk offline. Saya pernah salah ketik dan menghabiskan waktu cukup lama untuk sadar.

    Untuk service LDS-nya, gunakan zmlicensectl:

    zmlicensectl --service status       # Cek status service
    zmlicensectl --service start        # Start service
    zmlicensectl --service stop         # Stop service
    zmlicensectl --service setLogLevel=DEBUG  # Set level log untuk troubleshoot
    zmlicensectl --clearLicenseWorkDir  # Bersihkan working directory lisensi

    Memahami Grace Period

    Salah satu hal yang menurut saya cukup elegan di desain baru ini adalah konsep grace period. Mulai dari versi 10.1.10, kalau mailbox server kehilangan koneksi ke LDS selama kurang lebih 12 jam, sistem masuk ke mode grace period. Selama periode ini, mail flow tetap berjalan, tapi ada peringatan di admin console. Ini memberi kalian waktu untuk memperbaiki masalah konektivitas sebelum service benar-benar terganggu.

    Buat saya, ini menunjukkan bahwa Zimbra serius dengan reliability. Daripada langsung memutus service ketika ada masalah kecil di sisi lisensi, mereka memberi waktu untuk troubleshoot.

    Lokasi File Lisensi di 10.1

    Hal terakhir yang ingin saya luruskan. Di Zimbra 10.1, lisensi tidak lagi disimpan sebagai file XML statis di /opt/zimbra/conf/. Sekarang lokasinya di /opt/zimbra/license/store/, dan isinya bukan satu file XML melainkan beberapa file yang dikelola otomatis oleh LDS, seperti APV_secured.txt dan file pendamping lainnya.

    Jangan coba edit atau pindahkan file di direktori ini secara manual. Semua manipulasi harus lewat zmlicense dan zmlicensectl, supaya state internal LDS tetap konsisten.

    Refleksi Pribadi

    Yang saya pelajari dari mencoba memahami arsitektur ini adalah bahwa Zimbra 10.1 sebenarnya membawa Zimbra ke arah yang lebih modern dari sisi licensing. Mekanisme lama dengan file XML yang harus disalin manual antar server, validasi yang serba statis, dan license-daemon yang menempel di mailstore, semua itu adalah peninggalan era yang berbeda. Pendekatan baru dengan LDS sebagai service terpisah, dengan API, dengan grace period, dan dengan key alfanumerik untuk online, jauh lebih sejalan dengan praktik software modern.

    Tapi konsekuensinya, kalian harus berhati-hati membaca dokumentasi yang beredar di internet. Banyak artikel dan forum post yang relevan untuk Zimbra 8 atau 9, dan kalau diterapkan begitu saja ke 10.1, hasilnya akan keliru. Sumber paling aman adalah admin guide resmi Zimbra Daffodil v10 di zimbra.github.io/documentation/zimbra-10/. Saya akan menulis catatan lanjutan soal instalasi LDS di node terpisah dan troubleshoot LDS yang tidak running di postingan berikutnya, karena dua topik itu menurut saya cukup berdiri sendiri dan layak dibahas terpisah.

    Buat teman-teman yang sedang dalam perjalanan migrasi ke Zimbra 10.1, semoga catatan ini membantu meluruskan beberapa hal dasar sebelum kalian mulai menyentuh installer-nya. Lebih baik paham konsepnya dulu daripada kebingungan di tengah proses instalasi yang sudah berjalan setengah jalan.

  • Proxmox VE 9.2 Rilis: Catatan Fitur Baru dan Strategi Upgrade

    Proxmox VE 9.2 Rilis: Catatan Fitur Baru dan Strategi Upgrade

    Proxmox resmi merilis Virtual Environment versi 9.2. Saya kebetulan sedang aktif belajar Proxmox di lab pribadi dengan cluster tiga node, jadi rilis ini langsung menarik perhatian saya. Beberapa fitur barunya bahkan terasa “kebetulan banget” karena adalah hal yang baru-baru ini saya oprek manual di lab. Di tulisan ini, saya rangkum poin penting rilisnya, sekalian saya bahas catatan upgrade yang menurut saya wajib diketahui sebelum tergoda untuk langsung naik versi.

    Stack di Balik Rilis Ini

    Proxmox VE 9.2 berdiri di atas kombinasi versi berikut:

    • Debian 13.5 Trixie sebagai base OS
    • Linux kernel 7.0 sebagai default stable
    • QEMU 11.0 untuk virtualisasi KVM
    • LXC 7.0 untuk container
    • ZFS 2.4
    • Ceph Tentacle 20.2.1 sebagai default stable yang baru, dengan Ceph Squid 19.2.3 tetap tersedia sebagai opsi

    Lompatan dari PVE 9.0 yang masih pakai kernel 6.14 ke kernel 7.0 di 9.2 ini cukup signifikan. Kernel baru membawa dukungan hardware modern yang lebih luas, tapi sekaligus jadi alasan kenapa saya tidak akan langsung upgrade cluster lab tanpa testing dulu.

    Highlight Fitur Baru

    Yang paling impactful dari daftar fiturnya adalah:

    • Dynamic Load Balancer native untuk pemerataan resource cluster otomatis. Sebelumnya, fitur seperti ini biasanya didapatkan lewat project pihak ketiga seperti ProxLB. Sekarang sudah jadi bagian inti, jauh lebih maintainable untuk production.
    • WireGuard sebagai fabric protocol baru di SDN, melengkapi protocol yang sudah ada. Ini bisa menyederhanakan setup overlay network terenkripsi antar node, terutama untuk skenario site-to-site.
    • BGP/EVPN dengan route maps dan prefix lists, jadi filtering route antar fabric sekarang bisa jauh lebih granular. Berguna untuk skenario multi-tenant.
    • Custom CPU model dari GUI, tidak perlu lagi edit /etc/pve/datacenter.cfg manual. Kecil tapi praktis.
    • HA arm/disarm toggle, biar cluster tidak panik dan trigger fence saat kita sengaja maintenance node.
    • Enrollment sertifikat Microsoft dan Windows UEFI 2023 lewat GUI dan API, mempermudah deployment guest Windows dengan Secure Boot aktif.
    • Bugfix dan perbaikan performa di banyak area lain di seluruh platform.

    Catatan Upgrade

    Bagian ini saya rangkum dari FAQ resmi Proxmox, karena pertanyaan-pertanyaan ini hampir pasti akan muncul di forum dan grup beberapa hari ke depan.

    Upgrade dari Proxmox VE 8.4 ke 9.2 bisa dilakukan via apt. Ikuti panduan resmi Upgrade from 8 to 9 di wiki. Jangan lupa jalankan pve8to9 checker dulu untuk mendeteksi konfigurasi yang berpotensi bermasalah setelah upgrade.

    Upgrade dari 9.1 ke 9.2 bisa dilakukan via apt maupun GUI. Untuk pengalaman paling stabil, Proxmox menyarankan switch ke repository pve-enterprise saat upgrade.

    Proxmox VE 8.4 akan tetap menerima security update dan bugfix kritis sampai Agustus 2026. Itu memberi sekitar satu tahun overlap untuk perencanaan migrasi. Buat environment besar dengan dependency vendor, gunakan window ini untuk testing menyeluruh, jangan tunggu mepet deadline.

    Proxmox VE 9.2 bisa dipasang di atas instalasi Debian 13 Trixie yang sudah ada. Panduannya tersedia di wiki resmi.

    Untuk cluster PVE 8.4 dengan Ceph Reef yang ingin naik ke PVE 9.2 dengan Ceph Squid atau Tentacle, prosesnya tiga langkah dan urutannya tidak boleh dibolak-balik:

    1. Upgrade Ceph dari Reef ke Squid dulu, sementara masih di PVE 8.4.
    2. Setelah Ceph stabil di Squid, upgrade Proxmox VE dari 8.4 ke 9.2.
    3. Setelah PVE 9.2 stabil, baru upgrade Ceph dari Squid ke Tentacle.

    Loncat langsung dari Reef ke Tentacle berisiko merusak cluster karena setiap layer punya compatibility matrix yang ketat. Ikuti dokumentasi resmi secara berurutan, jangan dipotong langkahnya.

    Best Practice Singkat Sebelum Upgrade

    Beberapa hal yang biasa saya pegang sebelum naik versi di lab maupun production:

    1. Baca release notes resmi dulu, terutama section known issues.
    2. Pastikan backup PBS sudah berjalan dan terverifikasi sebelum mulai.
    3. Upgrade satu node dulu kalau cluster, monitoring 24 jam, baru lanjut node berikutnya.
    4. Sediakan window maintenance yang cukup, kernel dan stack berubah cukup banyak di rilis ini.

    Penutup

    Proxmox VE 9.2 bukan rilis dengan fitur eksperimental yang berisiko, melainkan rilis pematangan yang banyak menambahkan polish dan native support untuk hal-hal yang selama ini dilakukan dengan workaround. Buat saya pribadi, Dynamic Load Balancer dan WireGuard fabric adalah dua yang paling menarik untuk diuji di lab.

    Tapi sekali lagi, jangan terburu-buru upgrade production. Test di lab, baca release notes, dan kalau cluster kalian ada Ceph, perhatikan baik-baik urutan upgrade tiga langkah yang saya sebutkan di atas. Saya akan tulis ulasan lanjutan setelah eksperimen di lab saya jalan.

    Referensi:

  • Catatan Carbonio: Inventory di Ansible Galaxy Carbonio

    Catatan Carbonio: Inventory di Ansible Galaxy Carbonio

    Sejak saya pertama kali ikut training Carbonio oleh Zextras, salah satu hal yang menarik perhatian saya adalah cara Zextras menyediakan playbook resmi lewat Ansible Galaxy. Bukan sekadar script install biasa, tapi sebuah role yang siap deploy seluruh komponen Carbonio dari satu titik. Dan kunci dari semua itu ada di satu file: inventory.

    Di tulisan ini saya mau bahas singkat soal apa itu inventory di konteks Carbonio Ansible, isinya apa saja, dan kenapa setiap grup di dalamnya penting kalian pahami sebelum tekan enter pada perintah ansible-playbook.

    Apa Itu Inventory Carbonio

    Secara konsep, inventory di Ansible adalah daftar host beserta peran masing-masing. Di Carbonio, inventory ini berfungsi sebagai peta jalan: server mana yang akan jadi mailbox, mana yang jadi MTA, mana yang menjalankan Consul, dan seterusnya. Ansible akan baca file ini lalu mengeksekusi task yang sesuai di setiap node sesuai grupnya.

    Ada dua varian playbook resmi yang tersedia di Ansible Galaxy:

    • zxbot.carbonio_install untuk skenario multi-server (essential, full-standard, full-redundant)
    • zxbot.carbonio_ssinstall untuk skenario single-server

    Dua varian ini punya struktur inventory yang mirip, tapi tidak identik. Beberapa grup yang muncul di multi-server justru tidak boleh diisi di single-server.

    Catatan Sebelum Mengisi Inventory

    Tiga hal yang sering bikin instalasi gagal kalau diabaikan:

    1. Inventory hanya menerima FQDN, bukan IP address. Pastikan resolusi DNS internal sudah jalan, atau setidaknya /etc/hosts sudah diisi konsisten di semua node.
    2. Multi-master untuk directory server (LDAP) tidak didukung. Cuma boleh satu master, sisanya replica.
    3. dbsConnector akan otomatis dipasang di server Postgres, jadi grup [dbsConnectorServers] di skenario standar harus dibiarkan kosong. Grup ini baru relevan kalau kalian pakai HA dengan Patroni (versi 24.12.0 ke atas).

    Isi Inventory dan Peran Setiap Grup

    Berikut grup-grup utama yang kalian akan temui di file inventory Carbonio, beserta peran singkatnya:

    Komponen inti (wajib ada)

    • [postgresServers]: database utama untuk metadata Carbonio dan storage Files
    • [masterDirectoryServers]: LDAP master, satu-satunya sumber kebenaran untuk akun dan domain
    • [replicaDirectoryServers]: LDAP replica untuk redundansi (opsional di single-server)
    • [serviceDiscoverServers]: Consul, service mesh yang menghubungkan semua komponen Carbonio
    • [mtaServers]: Postfix, gerbang masuk dan keluar email
    • [proxyServers]: Nginx proxy untuk webmail, IMAP, POP, dan trafik HTTP
    • [applicationServers]: mailbox server, tempat data email sebenarnya disimpan

    Variabel penting

    • [proxyServers:vars] dengan webmailHostname=mail.example.com: hostname publik yang dipakai user untuk akses webmail

    Komponen opsional (fitur kolaborasi)

    • [filesServers]: Carbonio Files, fitur cloud storage internal
    • [docsServers]: Carbonio Docs, editor dokumen kolaboratif
    • [taskServers]: modul tasks
    • [previewServers]: service untuk preview file di webmail dan Files
    • [videoServers]: Carbonio Meeting, harus disertai public_ip_address=x.y.z.t di sebelah hostname
    • [workStreamServers]: chat dan messaging

    Komponen observability

    • [prometheusServers]: metrics collector
    • [syslogServer]: sentralisasi log

    Perbedaan di Skenario Single-Server

    Kalau kalian pakai zxbot.carbonio_ssinstall, semua grup inti di atas diarahkan ke satu hostname yang sama. Beberapa komponen opsional seperti taskServers, docsServers, videoServers, dan workStreamServers boleh dipisah ke VM lain, atau dikomentari kalau memang tidak dipakai. Grup [dbsConnectorServers] harus tetap kosong karena tidak didukung di single-server.

    Best Practice

    Beberapa hal yang saya pelajari selama training dan ngulik di lab:

    1. Simpan inventory di direktori khusus, misal ~/carbonio-inventories/lab/, supaya bisa kelola beberapa environment paralel
    2. Beri nama file inventory yang deskriptif (bukan sekadar inventory), karena nama file ini akan jadi prefix untuk file password yang digenerate seperti inventoryname_postgrespassword, inventoryname_ldap_password, dan inventoryname_consulpassword
    3. Selalu pakai versi playbook yang sesuai dengan versi Carbonio target. Versi playbook dan versi Carbonio saling terikat
    4. Sebelum jalankan playbook, validasi dulu dengan ansible all -i inventoryname -m ping untuk memastikan semua node bisa dihubungi via SSH
    5. Backup file inventory dan file password ke tempat aman setelah instalasi, karena file yang sama dipakai lagi untuk upgrade lewat zxbot.carbonio_upgrade

    Penutup

    Inventory di Carbonio Ansible itu bukan sekadar daftar hostname. Dia adalah dokumen arsitektur instalasi kalian dalam bentuk paling padat. Sekali kalian paham peran setiap grup, kalian sudah punya mental model yang cukup untuk memahami bagaimana komponen-komponen Carbonio saling terhubung di balik layar, termasuk waktu nanti harus troubleshoot kalau ada service yang ngambek.

    Untuk eksplorasi lebih lanjut, dua repo resmi Zextras yang saya rekomendasikan kalian baca: carbonio-install-ansible dan carbonio-ansible-ssinstall di GitHub. Di sana kalian bisa lihat contoh inventory lengkap untuk masing-masing skenario, sekalian ngintip role-nya kalau penasaran sama yang terjadi di balik layar.