Author: Rafi Harlianto

  • Install dan Konfigurasi Postfix di Rocky 9

    Install dan Konfigurasi Postfix di Rocky 9

    Pada panduan ini saya akan membahas instalasi Postfix di Rocky Linux 9 dari kondisi fresh install. Targetnya dua, pertama Postfix bisa kirim email antar user lokal, dan lalu ditingkatkan supaya bisa mengirim ke alamat Gmail menggunakan relay smtp.gmail.com. Namun untuk hari ini hanya sampai di antar user lokal saja. Semua perintah dijalankan sebagai root.

    Informasi Lab

    ItemNilai
    OSRocky Linux 9
    Hostnamemail.rafi.lab
    Domainrafi.lab
    IP Address192.168.14.4/24
    KebutuhanAkses root, internet

    Sesuaikan hostname dan domain dengan lingkungan kalian.

    1. Persiapan Server

    Set hostname dan tambahkan mapping di /etc/hosts:

    hostnamectl set-hostname mail.rafi.lab
    echo "192.168.14.4 mail.rafi.lab mail" >> /etc/hosts

    Update sistem:

    dnf update -y

    (Opsional) Buka port SMTP di firewalld supaya klien lain di jaringan lokal bisa mengirim lewat server ini:

    firewall-cmd --add-service=smtp --permanent
    firewall-cmd --reload

    SELinux biarkan enforcing, Postfix dengan konfigurasi standar tidak bermasalah.

    2. Instalasi Postfix

    Install Postfix beserta s-nail (pengganti mailx di Rocky 9, menyediakan perintah mail untuk pengujian) dan telnet:

    dnf install postfix s-nail telnet -y
    systemctl enable --now postfix

    Verifikasi:

    systemctl status postfix
    postconf mail_version

    Status service harus active(running).

    3. Konfigurasi Dasar Postfix

    Ubah parameter utama di /etc/postfix/main.cf. Cara paling aman menggunakan postconf:

    postconf -e 'myhostname = mail.rafi.lab'
    postconf -e 'mydomain = rafi.lab'
    postconf -e 'myorigin = $mydomain'
    postconf -e 'inet_interfaces = all'
    postconf -e 'inet_protocols = ipv4'
    postconf -e 'mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain'
    postconf -e 'mynetworks = 127.0.0.0/8, 192.168.14.0/24'
    postconf -e 'home_mailbox = Maildir/'

    Penjelasan singkat:

    • inet_interfaces = all membuat Postfix listen di semua interface, bukan hanya localhost
    • mydestination menentukan domain yang diterima sebagai tujuan lokal
    • mynetworks menentukan subnet yang boleh relay lewat server ini
    • home_mailbox = Maildir/ menyimpan email di direktori ~/Maildir tiap user

    Cek sintaks lalu restart:

    postfix check
    systemctl restart postfix

    postfix check tidak menampilkan output apa pun jika konfigurasi benar.

    4. Uji Kirim Sesama User Lokal

    Buat dua user untuk pengujian:

    useradd budi
    useradd andi

    Kirim email dari budi ke andi:

    su - budi -c 'echo "Halo Andi, ini tes email lokal" | mail -s "Tes Lokal" andi@rafi.lab'

    Cek email masuk di Maildir milik andi:

    ls /home/andi/Maildir/new/
    cat /home/andi/Maildir/new/*

    Cek log pengiriman:

    tail /var/log/maillog

    Opsional, kalian juga bisa tes lewat sesi SMTP manual:

    telnet 192.168.14.4 25

    Lalu ketik perintah SMTP berikut satu per satu (enter):

    ehlo rafi.lab
    mail from: budi@rafi.lab
    rcpt to: andi@rafi.lab
    data
    Subject: Tes via telnet
    
    Halo, ini tes lewat telnet
    .
    quit

    Sampai tahap ini Postfix sudah berfungsi untuk pengiriman antar user lokal.

  • Troubleshoot Zimbra Level 1: MTA yang Berhenti

    Troubleshoot Zimbra Level 1: MTA yang Berhenti

    Tulisan saya kali ini yaitu, catatan satu ronde latihan drill troubleshooting di lab Zimbra. Aturannya saya susun sendiri bersama Claude Code, Claude yang menyuntikkan fault ke server lab tanpa memberi tahu apa yang dirusak, saya yang mendiagnosis dan memperbaiki. Level 1 ini pemanasan, satu masalah dengan error yang seharusnya cukup terang kalau saya cek di tempat yang benar. Ada baiknya baca dulu Latihan Troubleshooting dengan Claude Code di tulisan saya sebelumnya agar paham konsep dan aturan main drill-nya.

    Tiket

    Sesi dimulai seperti biasa, saya pilih platform Zimbra dan level 1, Claude memastikan SSH ke node lab jalan dan snapshot sudah ada, lalu menyuntikkan fault-nya secara diam-diam. Yang saya terima cuma ini:

    Tiket: «User lapor email keluar dan masuk berhenti total sejak beberapa menit lalu. Webmail masih bisa login, tapi kirim email nyangkut.»

    Aturan mainnya disebutkan di awal: saya kerja sendiri, boleh minta hint kalau perlu, dan tiap hint mengurangi skor.

    Investigasi

    Tidak ada informasi lain selain tiket di atas. Karena webmail masih bisa diakses tapi pengiriman macet, langkah pertama saya selalu sama, lihat status zimbra dulu:

    Via CLI

    su - zimbra
    zmcontrol status

    Ketemu. Komponen mta dan yang berhubungan dengan mta stopped, komponen yang menjalankan Postfix. Ini sesuai dengan tanda-tanda nya, webmail (mailbox) jalan, tapi pengiriman (mta) mati.

    Tips: Sebelum menyalakan apa pun, cek dulu antrian mail untuk pastikan email cuma tertahan, bukan hilang:

    su - zimbra -c 'mailq'

    Coba Fitur Hint

    Karena ada fitur hint di drill ini, saya sengaja minta supaya tahu seperti apa bentuk hint nya.

    Claude kasih Hint 1 (dari 3 hint) sesuai urutan bertingkat yang sudah dia siapkan: «Ini bukan masalah mailbox/store, gejalanya di layer pengiriman (MTA).» Isinya memang sudah ketemu lewat zmcontrol status, jadi saya lanjut ke fix tanpa minta hint kedua.

    Fix

    Tinggal nyalakan lagi komponen MTA-nya:

    su - zimbra 
    zmmtactl start

    Setelah zmcontrol status saya cek ulang dan semua komponen kembali «Running», saya bilang ke Claude Code kalau saya sudah selesai.

    Verifikasi

    Claude tidak langsung percaya status «Running» saja. Dia jalankan verifikasi fungsional lewat SSH ke node lab: cek ulang zmcontrol status, cek mailq untuk pastikan antrian yang tadi tertahan mulai jalan, lalu kirim email uji dan bandingkan hasilnya ke baseline yang direkam sebelum fault disuntikkan. Semua cocok, gejalanya hilang karena root cause-nya memang sudah benar diperbaiki, bukan cuma ditutupi.

    Debrief dan skor

    Baru di titik ini Claude membuka kartunya. Root cause-nya persis seperti dugaan saya, service MTA (Postfix) dihentikan manual lalu dinyalakan kembali. Claude jelaskan kenapa fault ini realistis, di dunia nyata ini sering kejadian waktu ada maintenance atau restart manual yang lupa dinyalakan lagi setelahnya.

    Skor saya 8.5 dari 10, dipotong karena pakai satu hint meski sebenarnya lebih untuk coba-coba daripada kebutuhan. Hasil ini dicatat ke progress.md di project drill saya, jadi kelihatan riwayatnya kalau saya naik level nanti.

    Penutup

    Ronde ini singkat, cek status dulu secara menyeluruh sebelum menyentuh apa pun yang kelihatan mati. Level 1 memang dirancang begitu, satu masalah, error yang cukup terang asal dicek di tempat yang benar. Sampai jumpa di Level 2.

  • Latihan Troubleshooting dengan Claude Code

    Latihan Troubleshooting dengan Claude Code

    Jadi hari ini saya mencoba mengasah kemampuan troubleshooting, khususnya pada aplikasi yang dapat diimplementasikan secara on-premise seperti mail server (Zimbra dan Carbonio), platform virtualisasi (Proxmox VE), serta file management (Nextcloud). Menurut saya, kemampuan troubleshooting adalah salah satu keterampilan yang harus terus diasah karena sangat dibutuhkan saat mengelola infrastruktur. Namun, ada satu hal yang sampai sekarang masih sering membuat saya bingung ketika ingin belajar troubleshooting, diantara lain:

    • Saya gonta-ganti konfigurasinya sendiri (oprek)
    • Menunggu ada update/patch/bug terbaru
    • atau, menunggu aplikasi failure/error dengan sendirinya

    Kalau oprek sendiri dengan skill teknis minim seperti saya malah-malah merembet kemana-mana, kalau menunggu update bisa berbulan-bulan, dan apalagi kalau nunggu aplikasi failure nanti malah tidak latihan.

    Masalahnya, menunggu insiden itu tidak efisien. Jadi saya balik logikanya. Saya menjadikan Claude Code untuk merusak lab saya sendiri dengan pola yang realistis, lalu saya yang mendiagnosis dan memperbaiki. Anggap saja latihan tanding, tapi lawannya adalah AI yang paham error apa saja yang biasa terjadi di Proxmox, Nextcloud, Zimbra, atau Carbonio.

    Konsepnya

    Aturannya cuma satu yang penting: Claude berperan sebagai fasilitator, bukan tukang benerin. Tugas dia merusak, memberi gejala, dan memberi petunjuk kalau saya mentok. Yang mendiagnosis dan memperbaiki tetap saya.

    Alurnya kira-kira begini:

    1. Saya pilih platform dan level kesulitan.
    2. Claude menyuntikkan satu fault via SSH, tanpa memberi tahu apa yang dia rusak. (sebenernya mau pake MCP tapi belum paham)
    3. Saya cuma dikasih gejala, seperti tiket dari user. Misalnya “email keluar nyangkut sejak pagi”.
    4. Saya investigasi sendiri. Kalau mentok, boleh minta hint, tapi skornya berkurang.
    5. Setelah saya bilang selesai, Claude verifikasi dan kasih skor.

    Kuncinya ada di poin ketiga. Saya tidak dikasih tahu root cause-nya. Persis seperti simulasi production, saya cuma pegang gejala dan harus menelusuri sendiri sampai ke akar.

    Level 1 sampai 5

    Biar latihannya naik kelas, saya bagi lima level. Makin tinggi, makin dekat ke insiden produksi yang sebenarnya.

    LevelKarakter faultContoh
    1Satu masalah jelas, error terang di logService ke-stop, typo di config
    2Satu masalah, gejala kurang gamblangPort diblok firewall, cert expired
    3Gejala tak langsung lewat dependensiLDAP mati bikin semua auth gagal
    4Cascading, satu akar banyak gejalaDisk penuh, quorum cluster hilang
    5Beberapa masalah sekaligus, butuh metodeFault kombinasi lintas layer

    Level 1 itu pemanasan. Level 5 memaksa saya berpikir sistematis, memisahkan gejala satu per satu, dan menahan diri dari asumsi buru-buru.

    Penutup: Backup, backup, backup

    Sengaja merusak sistem tetap butuh rem. Ada dua aturan yang dibutuhkan

    • Pertama, backup atau snapshot dulu sebelum apa pun.
    • Kedua, kunci jawaban terpisah di folder sementara. Kalau saya baca duluan, latihan jadi percuma. Biar disiplin aja.

    Latihan ini akan dijalankan besok. Stay tune!

  • Bagian 1: Mengenal SMTP Relay

    Bagian 1: Mengenal SMTP Relay

    Pada minggu-minggu terakhir, saya mulai cukup banyak bersinggungan dengan layanan SMTP Relay, seperti pengaturan DNS seperti SPF, DKIM, dan DMARC. Dari situ saya menyadari bahwa banyak istilah dan konsep yang selama ini sering digunakan ternyata belum benar-benar saya pahami secara menyeluruh.

    Karena itu, saya memutuskan untuk membuat sebuah seri tulisan yang membahas dasar-dasar SMTP dan SMTP Relay. Tujuannya bukan hanya sebagai dokumentasi pembelajaran pribadi, tetapi juga sebagai referensi bagi siapa saja yang ingin memahami bagaimana proses pengiriman email bekerja, peran server relay, serta teknologi pendukung seperti SPF, DKIM, DMARC, MX Record, hingga alur komunikasi antar mail server. Saya berharap melalui seri ini, pembahasan dapat disampaikan secara bertahap, dimulai dari konsep yang paling mendasar hingga implementasi yang lebih kompleks.

    Apa itu SMTP, sebenarnya?

    SMTP adalah singkatan dari Simple Mail Transfer Protocol. Perhatikan kata pertamanya: Simple. Protokol ini dirancang pada tahun 1982 (RFC 821, lalu diperbarui oleh RFC 5321) dengan filosofi yang sederhana — bagaimana caranya memindahkan sebuah pesan teks dari satu komputer ke komputer lain secara andal.

    Analogi yang paling sering saya pakai: SMTP itu seperti kantor pos dan tukang pos, bukan seperti kotak surat di rumah kalian. Ini penting, jadi saya tegaskan:

    • SMTP bertugas mengirim dan meneruskan email antar server. Ini pekerjaan “tukang pos”.
    • IMAP dan POP3 bertugas agar kalian bisa mengambil dan membaca email dari kotak surat kalian. Ini pekerjaan “membuka kotak surat di rumah”.

    Salah satu kesalahpahaman paling umum yang saya temui: orang mengira SMTP itu untuk membaca email. Bukan. SMTP hanya peduli pada satu hal — memindahkan surat ke tujuan berikutnya.

    Mengenal: MUA, MTA, MDA

    Sebelum masuk ke kata “relay”, kalian wajib kenal tiga singkatan ini. Saya akan pakai istilah-istilah ini terus sepanjang seri, jadi hafalkan baik-baik.

    IstilahKepanjanganPeranContoh nyata
    MUAMail User AgentAplikasi yang kalian pakai untuk menulis & membaca emailOutlook, Thunderbird, Gmail di browser
    MTAMail Transfer AgentServer yang mengirim & meneruskan email antar serverPostfix, Exim, Sendmail
    MDAMail Delivery AgentKomponen yang menaruh email ke kotak surat penerimaDovecot, procmail

    Alur singkatnya begini: kalian menulis email di MUA, MUA menyerahkannya ke MTA, MTA mengoper email itu melewati internet ke MTA lain, lalu di ujung sana MDA menaruhnya ke inbox penerima. Server relay yang akan saya urus (dan yang jadi bintang seri ini) hidup di lapisan MTA.

    Lalu, apa itu “Relay”?

    Nah, sekarang kata kuncinya. Relay dalam konteks email berarti meneruskan email dari satu titik ke titik lain, di mana server yang meneruskan bukanlah pengirim asli maupun penerima akhir.

    Bayangkan estafet lari. Pelari pertama (pengirim) tidak berlari sampai garis finish. Ia memberikan tongkat ke pelari kedua, yang memberikannya lagi ke pelari berikutnya, sampai akhirnya tongkat mencapai finish (penerima). SMTP relay adalah pelari di tengah — ia menerima tongkat (email) lalu meneruskannya ke tujuan berikutnya.

    Kenapa perlu perantara? Kenapa email tidak langsung terbang dari komputer kalian ke server tujuan? Beberapa alasan:

    1. Sentralisasi & kontrol. Perusahaan ingin semua email keluar lewat satu pintu agar bisa dipantau, dicatat, dan diamankan.
    2. Reputasi IP. Server tujuan (misalnya Gmail) menilai email dari reputasi alamat IP pengirim. Mengirim lewat relay dengan IP bereputasi baik jauh lebih mungkin masuk inbox ketimbang dari IP rumahan.
    3. Aplikasi yang tidak mau repot. Aplikasi web, printer, perangkat IoT — mereka tidak mau mengurus antrian, retry, dan enkripsi. Mereka cukup “menitipkan” email ke relay, lalu relay yang mengurus sisanya.
    4. Batasan ISP. Banyak penyedia internet memblokir port 25 dari koneksi rumahan untuk mencegah spam, sehingga mengirim langsung sering kali mustahil.

    Dua wajah SMTP relay

    Ini bagian yang sering bikin bingung pemula, jadi saya pisahkan dengan jelas. Ada dua konteks besar ketika orang menyebut “relay”:

    • Relay sebagai layanan titip-kirim (smarthost). Server aplikasi kalian tidak mengirim langsung ke internet, melainkan menyerahkan semua email ke satu relay tepercaya (disebut smarthost). Relay inilah yang berhubungan dengan dunia luar. Inilah pola yang paling umum di lingkungan korporat.
    • Open relay — dan kenapa ini mimpi buruk. Di masa lalu, banyak server mau meneruskan email dari siapa saja ke siapa saja. Ini disebut open relay. Para spammer menyalahgunakannya besar-besaran untuk menyemburkan jutaan email sampah. Hari ini, open relay adalah dosa besar dalam administrasi email. Server kalian akan langsung masuk daftar hitam (blacklist) global dalam hitungan jam. Salah satu tugas utama saya nanti — dan tema besar di bagian ke-5 seri ini — adalah memastikan relay kita tertutup rapat dan hanya mau melayani pihak yang berwenang.

    Saya tekankan sekali lagi karena ini krusial: relay yang baik itu selektif. Ia tahu persis siapa yang boleh menitip email lewat dirinya, dan menolak semua yang lain.

    Kapan kalian butuh SMTP relay?

    Supaya konkret, ini beberapa skenario nyata di mana relay jadi jawaban:

    • Aplikasi e-commerce kalian perlu mengirim ribuan email “pesanan diterima” per hari, dan kalian ingin semuanya terkirim rapi dengan reputasi terjaga.
    • Kantor punya banyak aplikasi internal (HR, monitoring, printer) yang perlu kirim notifikasi, dan kalian ingin satu titik keluar yang terkontrol.
    • Kalian punya banyak server yang tersebar, tapi ingin semua email keluar melalui satu IP yang sudah dikonfigurasi SPF, DKIM, dan DMARC-nya dengan benar (tenang, semua istilah ini kita bedah tuntas di bagian ke-4).

    Peta perjalanan seri ini

    Karena ini seri berkelanjutan, saya ingin kalian tahu ke mana kita akan pergi. Anggap ini peta perjalanan kita:

    1. Bagian 1 (yang sedang kalian baca): Fondasi — apa itu SMTP dan relay.
    2. Bagian 2: Anatomi perjalanan sebuah email, percakapan SMTP baris demi baris, port, dan istilah DNS seperti MX record.
    3. Bagian 3: Oprek-oprek, membangun relay pertama dengan Postfix dari nol.
    4. Bagian 4: Keamanan & deliverability — TLS, autentikasi SASL, SPF, DKIM, DMARC.
    5. Bagian 5: Menjaga relay tetap sehat — anti-spam, rate limiting, mencegah open relay, dan membaca log saat ada masalah.
    6. Bagian 6: Level produksi — high availability, manajemen antrian, dan monitoring.

    Penutup

    Sampai sini, saya harap gambaran besarnya sudah terbentuk di kepala kalian: SMTP adalah bahasa yang dipakai server email untuk berbicara, dan relay adalah peran perantara yang meneruskan email dengan penuh tanggung jawab.

    Di bagian berikutnya, kita akan menyelami sesuatu yang menurut saya paling seru — kita akan “menguping” percakapan asli antara dua server SMTP, baris demi baris, sampai kalian bisa membaca dan bahkan mengetiknya sendiri dengan tangan. Sampai jumpa di Bagian 2.

  • Upgrade Carbonio 26.3 ke 26.6.0 via Ansible

    Upgrade Carbonio 26.3 ke 26.6.0 via Ansible

    Hari ini Carbonio rilis versi 26.6.0, jadi langsung saya coba upgrade di server single-server saya pakai metode resmi berbasis Ansible. Prosesnya sebenarnya cukup mulus, cuma di akhir saya sempat kena masalah carbonio-tasks yang tidak jalan. Berikut catatan lengkapnya, dari kondisi awal sampai troubleshoot.

    Cek Versi Awal

    Sebelum mulai, saya cek dulu versi yang terpasang. Kebiasaan yang selalu saya lakukan, biar tahu titik awalnya dan bisa dibandingkan setelah upgrade.

    root@mail:~# su - zextras -c "zmcontrol -v"
    Carbonio Release 26.3.2
    Advanced module version:
    
    CLI versions:
    
    zextras_version       26.3.1
    zextras_commit 97dbab6a7491843684b80e95ecb2fb0d1d2442b0
    zal_version           26.3.1
    zal_commit     6db124701ef6e49a44951a025c432fc4f4f2bd9d
    
    Server versions:
    
    version               26.3.1
    commit         97dbab6a7491843684b80e95ecb2fb0d1d2442b0
    system_type           carbonio
    product               Carbonio
    zal_version           26.3.1
    zal_commit     6db124701ef6e49a44951a025c432fc4f4f2bd9d
    

    Posisi saya di 26.3.x dan target hari ini 26.6.0.

    Install atau Update Collection carbonio_upgrade

    Metode upgrade via Ansible dijalankan dari Control Node, bukan dari server Carbonio-nya. Pertama, pastikan collection upgrade selalu versi terbaru. Flag -U artinya install kalau belum ada, atau update ke versi terbaru kalau sudah ada.

    root@ansible:~# ansible-galaxy collection install \ zxbot.carbonio_upgrade -U

    Cek Inventory

    Sebelum jalan, saya cek dulu file inventory. Ini file yang sama yang dipakai waktu instalasi awal, isinya daftar node dan group sesuai infrastruktur. Untuk single-server semuanya menunjuk ke satu host yang sama.

    Sebelum menjalankan playbook, ada beberapa hal yang wajib kalian sadari. Ini bukan sekadar formalitas, saya sudah baca di dokumentasi resminya dan memang perlu diperhatikan:

    HalKenapa penting
    Playbook menghapus dependency yang tidak terpakaiTambahkan --extra-vars skip_autoremove=1 kalau tidak mau ada paket yang otomatis dibuang
    Playbook update SEMUA paket dari repo yang aktifBukan cuma paket Carbonio. Nonaktifkan atau komentari repo yang tidak ingin diikutkan
    Bisa di-run ulangKalau proses gagal di tengah jalan, jalankan lagi. Task yang sudah sukses akan di-skip
    Legacy Chats tidak disentuhKalau masih pakai Chats lama, tidak akan dihapus, dijadikan read-only, atau dimigrasi otomatis

    Poin soal “update semua paket dari repo aktif” ini yang menurut saya paling penting. Kalau ada repo pihak ketiga aktif, pastikan aman diikutkan, atau matikan dulu.

    Jalankan Upgrade

    Masuk ke direktori yang berisi inventory, lalu jalankan playbook upgrade.

    root@ansible:~# cd single-server-deploy
    root@ansible:~/single-server-deploy# ansible-playbook \ zxbot.carbonio_upgrade.carbonio_upgrade -u root -i \ inventory.yaml

    Setelah itu tinggal ditunggu. Prosesnya cukup lama karena mengunduh dan memasang banyak paket, jalankan bootstrap database, lalu register ulang ke Carbonio Mesh. Sabar saja, jangan diinterupsi di tengah jalan.

    Hasil

    Setelah menunggu cukup lama, hasilnya sesuai harapan:

    zextras@mail:~$ zmcontrol -v
    Carbonio Release 26.6.0

    Upgrade dari 26.3.x ke 26.6.0 berhasil.

    Penutup

    Upgrade via Ansible ini menurut saya cara paling nyaman untuk Carbonio, karena bootstrap database dan register Mesh sudah otomatis di dalam playbook. Yang perlu diwaspadai justru dua hal: perilaku autoremove dan update semua paket dari repo aktif.

    Catatan: perintah bootstrap dan sidecar di atas berbasis dokumentasi resmi dan forum Zextras. Kalau nama service atau path di versi kalian berbeda, selalu konfirmasi ke dokumentasi resmi versi yang kalian pakai sebelum dijalankan.

    Referensi

    • Upgrade Using Ansible (Carbonio Admin Guide): https://docs.zextras.com/carbonio/html/upgrade/ansible.html
    • Advanced Administration Tasks / pending-setups (Carbonio Admin Guide): https://docs.zextras.com/carbonio/html/admincli/advancedadmin.html
    • Tasks component (Carbonio CE Admin Docs): https://docs.zextras.com/carbonio-ce/html/architecture/components/component-tasks.html
  • Memahami dan Memaksimalkan Claude Code

    Memahami dan Memaksimalkan Claude Code

    Saya pakai beberapa AI code assistant, Claude Code, Antigravity, dan sejenisnya, tapi tulisan ini fokus ke Claude Code dan jadi bahan pembelajaran untuk saya yang masih pemula dalam penggunaannya. Prinsip di bawah ini sebagian besar berlaku juga untuk tool lain, cuma cara implementasinya beda-beda.

    Dua masalah paling sering muncul waktu kerja pakai AI code agent:

    1. Token cepat habis, usage limit kena padahal kerjaan belum kelar.
    2. Hasil kerja melenceng dari rencana, jadi harus dikoreksi berkali-kali.

    Catatan ini disusun dari dokumentasi resmi Claude Code (code.claude.com/docs).

    1. Hemat Token dan Usage Limit

    Akar masalahnya satu: context window. Makin penuh context, makin banyak token diproses ulang tiap pesan, dan performa ikut turun karena instruksi lama mulai “terlupakan”. Jadi strategi hemat token intinya jaga context tetap kecil dan relevan.

    StrategiKenapa penting
    Rapikan CLAUDE.mdFile ini kebaca tiap sesi, jadi ikut nambah token di tiap request. Isi cuma hal yang Claude tidak bisa tebak sendiri: perintah build khusus, konvensi kode beda dari default, gotcha project. Kalau satu baris dihapus dan Claude tetap benar, hapus saja
    /clear antar taskPindah task tapi context lama masih menumpuk itu boros. /clear reset total
    /compact <instruksi>Kasih arahan spesifik, misal /compact fokus ke perubahan API dan hasil test, biar ringkasan yang tersimpan relevan
    Reference file pakai @Sebut file spesifik, misal @src/auth/session.ts, daripada suruh Claude eksplorasi satu folder penuh
    Delegasikan riset ke subagentSubagent jalan di context terpisah, yang balik ke context utama cuma rangkumannya
    Pilih model sesuai beban kerjaSonnet cukup untuk kerjaan harian dan lebih murah. Simpan Opus untuk keputusan arsitektur atau analisis kompleks. Ganti lewat /model
    Pantau lewat /context dan /usage/context kasih breakdown token per komponen. /usage kasih estimasi biaya sesi berjalan

    2. Supaya Claude Code Jalan Sesuai Rencana

    Bagian ini paling sering diabaikan. Langsung suruh coding tanpa eksplorasi dan rencana biasanya menghasilkan kode yang terlihat benar tapi menjawab masalah yang salah.

    Alur resmi yang direkomendasikan ada empat tahap:

    1. Explore: masuk plan mode, suruh Claude baca dan pahami kode relevan dulu tanpa mengubah apa pun.
    2. Plan: minta Claude buat rencana implementasi detail. Bisa diedit manual dulu sebelum lanjut.
    3. Implement: keluar plan mode, biarkan Claude coding sambil verifikasi ke rencana yang disepakati.
    4. Commit: minta Claude commit dengan pesan jelas.

    Plan mode ada overhead-nya, jadi skip saja untuk perubahan kecil yang sudah jelas seperti perbaiki typo atau rename variabel. Pakai kalau perubahan menyentuh banyak file, atau kalian sendiri belum yakin pendekatan yang tepat.

    Dua kebiasaan lain yang paling berpengaruh ke akurasi hasil:

    Kasih konteks spesifik, bukan instruksi umum.

    Kurang spesifikLebih spesifik
    “tambahin test buat foo.py”“tulis test untuk foo.py, cover kasus user sudah logout, jangan pakai mock”
    “perbaiki bug login”“login gagal setelah session timeout, cek flow auth di src/auth/ terutama token refresh, buat failing test dulu baru diperbaiki”

    Kasih Claude cara verifikasi sendiri, entah test suite, build, atau screenshot dibanding desain awal. Tanpa itu, satu-satunya sinyal “kelar” cuma kode yang terlihat masuk akal, belum tentu benar.

    Untuk fitur besar, minta Claude interview kalian dulu soal implementasi teknis, UX, dan edge case, sebelum nulis spek ke file terpisah. Sesi implementasi baru dimulai setelah spek matang, jadi context-nya bersih dan fokus.

    Kalau sudah dikoreksi dua kali untuk masalah yang sama, jangan koreksi ketiga kalinya di sesi yang sama. /clear saja dan tulis ulang prompt yang lebih spesifik.

    Untuk kerjaan tanpa pengawasan, tambahkan satu langkah review dari subagent terpisah yang mengecek diff terhadap rencana awal, bukan sekadar gaya penulisan kode.

    3. Lain-lain

    • Hooks: aturan yang wajib jalan tanpa kecuali, misal lint otomatis tiap habis edit file. Deterministik, beda dari CLAUDE.md yang sifatnya cuma anjuran.
    • Skills: workflow berulang, bikin SKILL.md di .claude/skills/ daripada jelasin ulang tiap sesi.
    • Rename dan resume session: kasih nama sesi jelas pakai /rename per workstream, lanjut pakai --resume atau --continue.
    • Non-interactive mode: untuk kerjaan berulang atau otomasi, pakai claude -p "prompt" di script, pre-commit hook, atau CI.
    • Checkpoint dan rewind: tiap prompt otomatis bikin checkpoint. Kalau salah arah, tekan Esc dua kali atau jalankan /rewind.

    Pola gagal yang paling sering terjadi:

    Pola gagalCara mengatasi
    Satu sesi dipakai banyak task tidak nyambung/clear tiap ganti task
    Koreksi berulang tanpa hasil membaik/clear setelah dua kali gagal, tulis ulang prompt
    CLAUDE.md kepanjangan sampai instruksi penting ketutup noisePangkas ruthless
    Percaya hasil tanpa verifikasiSelalu sediakan cara ngecek
    Eksplorasi tanpa scope jelasBatasi cakupan riset atau delegasikan ke subagent

    Penutup

    Intinya satu: context adalah resource terbatas, perlakukan seperti resource, bukan tempat sampah. Makin bersih dan terarah context yang dikasih ke Claude Code, makin hemat token, dan makin kecil kemungkinan hasilnya melenceng dari rencana.

    Referensi:

    • Best practices for Claude Code, Anthropic. https://code.claude.com/docs/en/best-practices
    • Manage costs effectively, Anthropic. https://code.claude.com/docs/en/costs
  • Merancang Instalasi Otomatis Zimbra dengan Ansible

    Merancang Instalasi Otomatis Zimbra dengan Ansible

    Hari ini saya memulai untuk membangun project saya, yaitu project instalasi zimbra secara otomatis, dan disini saya menggunakan Ansible sebagai mesin otomasi nya. Instalasi Zimbra secara manual itu melelahkan. Kalian harus SSH ke server, menyiapkan hostname dan DNS, menjalankan install.sh, lalu menjawab puluhan pertanyaan interaktif di zmsetup.pl satu per satu. Ulangi proses ini untuk setiap server, dan satu salah ketik bisa membuat Anda mengulang dari awal.

    Di artikel ini saya akan menceritakan rancangan saya, bagaimana saya membangun sebuah dashboard yang menginstalasi Zimbra secara otomatis ke server target, cukup dengan mengisi parameter wajib lewat form. Mesin di belakangnya adalah Ansible. Dashboard mendukung dua edisi: Zimbra OSE (Open Source Edition) dan Zimbra NE (Network Edition).

    Kenapa Ansible?

    Ansible cocok untuk kasus ini karena beberapa alasan:

    • Agentless. Tidak perlu memasang apa pun di server target; cukup akses SSH dan Python (sudah ada di hampir semua distro Linux).
    • Idempotent. Menjalankan ulang playbook tidak merusak yang sudah benar — sangat penting untuk instalasi yang panjang.
    • Deklaratif. Anda mendeskripsikan kondisi akhir yang diinginkan, bukan urutan perintah manual.
    • Mudah dipasangkan dengan dashboard. Dashboard cukup men-generate file variabel dan inventory, lalu memanggil ansible-playbook.

    Arsitektur Solusi

    Alur kerjanya sederhana:

    [ Dashboard (form) ]
            │  generate
            ▼
    group_vars/all.yml  +  inventory/hosts.ini
            │  trigger
            ▼
    ansible-playbook site.yml
            │  SSH
            ▼
    [ Server target: Zimbra terpasang ]

    Dashboard hanya bertugas mengumpulkan parameter dari user, menuliskannya ke dua file, lalu menjalankan playbook. Seluruh logika instalasi hidup di dalam Ansible.

    Metode Instalasi Unattended

    Kunci otomasi Zimbra adalah membuat installer yang biasanya interaktif menjadi unattended. Saya mengikuti pendekatan resmi dari repo Zimbra (zinstaller), yang terbagi dua fase:

    Fase 1 — Install software saja. Jalankan installer dengan flag software-only dan suplai jawaban lewat answer file:

    ./install.sh -s < keystroke_answers

    Fase 2 — Konfigurasi unattended. Setelah paket terpasang, jalankan setup dengan file konfigurasi, bukan wizard interaktif:

    /opt/zimbra/libexec/zmsetup.pl -c /tmp/zim-install-config

    File zim-install-config berisi key konfigurasi resmi Zimbra (hostname, domain, password admin, komponen yang diaktifkan, dan seterusnya). Template inilah yang diisi dari parameter dashboard.

    Perbedaan OSE vs NE

    Bedanya terutama pada lisensi:

    • OSE — tidak butuh lisensi sama sekali.
    • NE 10.1.x — aktivasi memakai license KEY via zmlicense -a <key>.
    • NE ≤ 10.0 — memakai file lisensi (license.xml) yang ditunjuk lewat variabel LICENSEFILE.

    Dashboard cukup menampilkan field lisensi secara kondisional ketika user memilih edisi NE.

    Struktur Project Ansible

    instaru/
    ├── site.yml
    ├── inventory/
    │   └── hosts.ini
    ├── group_vars/
    │   └── all.yml          # semua parameter wajib di sini
    ├── roles/
    │   ├── preflight/       # cek hostname, DNS, resource, swap
    │   ├── zimbra_install/  # download, install.sh -s
    │   └── zimbra_config/   # render config, zmsetup.pl -c
    └── templates/
        └── zim-install-config.j2

    Parameter wajib (group_vars/all.yml)

    Inilah variabel yang dikumpulkan dashboard dari user:

    # Identitas
    zimbra_edition: "ose"          # ose | ne
    zimbra_version: "10.1.0"
    zimbra_hostname: "mail.example.com"
    zimbra_domain: "example.com"
    
    # Kredensial
    admin_password: "{{ vault_admin_password }}"
    ldap_password: "{{ vault_ldap_password }}"
    
    # Lisensi (hanya untuk NE)
    zimbra_license_key: ""         # NE 10.1.x
    zimbra_license_file: ""        # NE <=10.0
    
    # Komponen
    enable_proxy: true
    enable_spell: true
    timezone: "Asia/Jakarta"
    

    Simpan semua password di Ansible Vault, jangan plaintext. Dashboard bisa mengenkripsi nilai sensitif sebelum menulisnya ke file.

    Inventory & topologi

    Topologi dipilih lewat grup inventory. Untuk single-server semua peran di satu host; untuk multi-server, peran dipecah dan LDAP harus diinstall pertama.

    # Single server

    [zimbra_single]
    mail.example.com 

    atau

    # Multi-server

    [zimbra_ldap]
    ldap.example.com
    
    [zimbra_store] (mailbox/mbox)
    store.example.com
    
    [zimbra_mta]
    mta.example.com
    
    [zimbra_proxy]
    proxy.example.com

    Playbook Utama

    # site.yml
    - name: Validasi & persiapan server
      hosts: all
      become: true
      roles:
        - preflight
    
    - name: Install & konfigurasi Zimbra
      hosts: all
      become: true
      roles:
        - zimbra_install
        - zimbra_config
    

    Role preflight penting: ia memvalidasi bahwa hostname FQDN sudah benar, DNS A dan MX sudah resolve, RAM mencukupi, dan swap tersedia — kesalahan paling umum pada instalasi Zimbra ada di tahap ini, jadi lebih baik gagal cepat sebelum installer berjalan.

    Catatan dependensi: playbook ini membutuhkan koleksi community.general dan ansible.posix. Pasang dengan:

    ansible-galaxy collection install community.general ansible.posix

    Menjalankannya

    Dari dashboard, eksekusi akhirnya sesederhana ini:

    ansible-playbook -i inventory/hosts.ini site.yml --ask-vault-pass

    Dashboard menjalankan perintah ini sebagai background job, lalu menampilkan progres dengan men-stream output Ansible kembali ke UI. User cukup menunggu sampai status berubah menjadi selesai.

    Penutup

    Jika ini berhasil, maka saya tinggal membuat dashboard terintegrasi yang dapat melakukan instalasi zimbra hanya dengan beberapa input saja (ip, hostname, dll) dan akses ssh ke server target.

    Langkah pengembangan berikutnya yang saya rencanakan: validasi parameter real-time di sisi dashboard, dukungan rollback otomatis bila instalasi gagal di tengah jalan, dan template multi-server siap pakai.

  • Integrasi Proxmox Datacenter Manager (PDM) dengan Cluster PVE

    Integrasi Proxmox Datacenter Manager (PDM) dengan Cluster PVE

    Ini catatan percobaan instalasi saya dengan Proxmox Datacenter Manager (PDM). Instalasinya sendiri sudah saya lakukan cepat lewat ISO PDM, jadi di sini saya fokus ke bagian integrasinya dengan cluster PVE saya. PDM ini lapisan manajemen terpusat di atas beberapa node atau cluster Proxmox, jadi saya bisa pantau semua dari satu antarmuka tanpa buka banyak tab.

    Catatan sebelum integrasi

    • PDM harus bisa terhubung langsung ke remote PVE lewat API (port 8006). Remote sendiri tidak perlu bisa menghubungi PDM.
    • Reverse proxy antara PDM dan remote tidak didukung. Untuk remote lewat internet, pakai tunnel seperti WireGuard atau OpenVPN.
    • Versi minimum: Proxmox VE 8.4 dan Proxmox Backup Server 3.4.

    Akses web UI

    Setelah instalasi ISO selesai, akses lewat browser pakai HTTPS di port 8443.

    https://<ip-atau-dns-pdm>:8443

    Login pakai user root@pam dengan password yang diset saat instalasi.

    Menambahkan cluster PVE sebagai remote

    Di PDM, satu cluster atau node PVE disebut remote. Untuk cluster, cukup tambah satu node saja, PDM otomatis menemukan node lain di cluster yang sama.

    1. Buka menu Remotes lalu Add, pilih tipe Proxmox VE.
    2. Masukkan alamat salah satu node cluster, misalnya https://192.168.14.11:8006 untuk node rafi1.
    3. Login dengan user PVE (root@pam) beserta passwordnya. Wizard membuat API token otomatis sesuai izin user, jadi PDM tidak menyimpan password.
    4. Wizard akan probe sertifikat. Karena sertifikat Proxmox default itu self-signed, kalian diminta menerima fingerprint-nya (Trust On First Use). Pastikan fingerprint cocok sebelum menerima.
    5. Setelah ditambahkan, PDM menampilkan seluruh hierarki cluster, VM, container, dan storage.

    Yang bisa dilakukan setelah tersambung

    • Metrik terpusat (CPU, RAM, storage) dari semua remote dalam satu dashboard.
    • Start, stop, reboot guest tanpa login ke node satu per satu.
    • Live migration guest, bahkan antar cluster berbeda tanpa syarat jaringan cluster.
    • Update management terpusat untuk melihat dan menjalankan patch.
    • Overview Ceph, berguna untuk cluster yang pakai Ceph.

    Menemukan Fingerprint Node Proxmox

    Kasus yang sering muncul: sertifikat self-signed di node di-renew atau dirotasi, sehingga fingerprint yang dipin di PDM tidak cocok lagi. Koneksi ke remote itu akan gagal dengan error certificate verify failed.

    pvenode cert info --output-format json-pretty

    Cari fingerprint: diantara hasilnya.

    Penutup

    Sejauh percobaan ini, PDM mengisi celah yang selama ini merepotkan saat punya lebih dari satu node atau cluster. Integrasinya cukup mulus, dan satu remote sudah otomatis menarik seluruh node cluster.

    Referensi

    • Dokumentasi resmi PDM, Remotes: https://pdm.proxmox.com/docs/remotes.html
    • Dokumentasi resmi PDM, Installation: https://pdm.proxmox.com/docs/installation.html
    • Halaman produk PDM: https://www.proxmox.com/en/products/proxmox-datacenter-manager/overview
  • Perbedaan Repository Proxmox VE: Enterprise vs No-Subscription

    Perbedaan Repository Proxmox VE: Enterprise vs No-Subscription

    Waktu pertama install Proxmox VE, repository yang aktif secara default adalah Enterprise. Kalau kalian tidak punya subscription, apt update bakal error 401 Unauthorized dan tidak ada paket yang bisa di-update. Di sini saya jelaskan singkat bedanya repository Enterprise dan No-Subscription, plus kapan sebaiknya pakai yang mana.

    Sebenarnya Proxmox VE menyediakan tiga repository (di luar repo dasar Debian):

    • pve-enterprise: paling stabil, untuk produksi, butuh subscription.
    • pve-no-subscription: gratis, tanpa key, cocok untuk testing dan non-produksi.
    • pve-test: untuk developer yang mau coba fitur baru, jangan dipakai di produksi.

    Yang paling sering dibandingkan adalah dua yang pertama.

    Enterprise

    • Repo default dan direkomendasikan Proxmox untuk produksi.
    • Berisi paket paling stabil karena melewati testing dan validasi lebih ketat.
    • Butuh subscription aktif (level berapa pun).
    • URL: https://enterprise.proxmox.com/debian/pve

    No-Subscription

    • Gratis, tidak butuh subscription key.
    • Cocok untuk testing dan non-produksi seperti homelab atau lab belajar.
    • Paketnya tidak melalui testing seketat repo Enterprise, jadi update datang lebih cepat tapi risiko sedikit lebih tinggi.
    • Setelah beberapa waktu, versi paketnya juga masuk ke repo Enterprise.
    • URL: http://download.proxmox.com/debian/pve

    Tabel Perbandingan

    AspekEnterpriseNo-Subscription
    BiayaButuh subscription berbayarGratis
    KestabilanPaling stabil, validasi ketatKurang teruji, update lebih cepat
    RekomendasiProduksiTesting / non-produksi
    Subscription keyWajibTidak perlu
    Notifikasi “no valid subscription”Tidak munculMuncul di web UI
    Status defaultAktifPerlu diaktifkan manual

    Kapan Pakai yang Mana

    • Server produksi yang butuh stabilitas dan support resmi: pakai Enterprise (beli subscription).
    • Homelab, lab testing, belajar, atau budget terbatas: pakai No-Subscription.
    • Jangan aktifkan keduanya bersamaan. Pilih salah satu dan disable yang lain lewat web UI di Node > Updates > Repositories.
    • Repo Debian (base OS) jangan di-disable. Itu tetap diperlukan untuk paket di luar Proxmox.

    Catatan untuk Proxmox VE 9

    Mulai Proxmox VE 9 (basis Debian 13 Trixie), format repository pindah ke deb822 (.sources), bukan lagi one-line sources.list seperti di PVE 8 (Debian 12 Bookworm). Contoh stanza No-Subscription di file /etc/apt/sources.list.d/pve-no-subscription.sources:

    Types: deb
    URIs: http://download.proxmox.com/debian/pve
    Suites: trixie
    Components: pve-no-subscription
    Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg
    

    Soal notifikasi “You do not have a valid subscription”: ini wajar muncul kalau pakai No-Subscription dan aman diabaikan di node lab. Saya tidak menyarankan mengedit file JavaScript bawaan untuk menghilangkannya, karena perubahan itu bisa hilang atau rusak saat update dan bukan praktik resmi.

    Sumber

  • Mengatur Proxmox dari Handphone

    Mengatur Proxmox dari Handphone

    Selama ini saya mendalami dan mempelajari Proxmox, saya kira hanya dapat akses lewat web UI, di hp pun sudah pas sih untuk tampilan UI nya. Tapi, pas iseng baca-baca artikel, ternyata Proxmox bisa dipantau dan dikontrol langsung dengan menggunakan aplikasi berbasis android/ios. Berikut rangkuman yang saya pelajari, plus sedikit pendapat saya sebagai orang yang kadang sehari-hari pakai Proxmox.

    Sumber: How I Manage My Proxmox Cluster From My Phone (4 Mobile Tools I Use) – Virtualizationhowto

    Apa yang bisa dan tidak bisa dari HP

    Web UI desktop tetap tempat utama buat ngatur semua aspek cluster. HP cocoknya buat monitoring dan operasi cepat.

    Bisa dari HP:

    • Cek status node dan resource cluster
    • Start, stop, restart VM dan container
    • Pantau CPU dan memori
    • Lihat utilisasi storage
    • Baca system log

    Sebaiknya tetap dari desktop:

    • Konfigurasi jaringan
    • Manajemen storage
    • Konfigurasi level cluster
    • Perubahan infrastruktur kompleks

    4 tool yang dibahas

    1. Web UI mobile bawaan Proxmox

    Sejak Proxmox 9, web UI bawaan sudah ramah layar HP. Tinggal buka URL server di browser, tampilannya menyesuaikan.

    Kelebihan:

    • Tanpa instal aplikasi, cukup browser
    • Selalu kompatibel dengan rilis terbaru
    • Fitur admin cukup lengkap

    Kekurangan:

    • Masih ada yang belum bisa, contohnya snapshot

    2. Aplikasi resmi Proxmox

    Konek langsung ke API Proxmox. Lebih praktis dari browser karena ingat koneksi dan dukung login biometrik.

    Kelebihan:

    • Mudah dipakai
    • Info resource lengkap
    • Operasi power VM seperti start, stop, dan reboot
    • Login biometrik

    Kekurangan:

    • Tidak ada manajemen detail
    • Tidak ada manajemen snapshot
    • Tidak bisa kelola PBS

    3. Proxmobo

    Aplikasi pihak ketiga dengan dashboard rapi. Menurut penulis, grafik resource-nya paling bagus di antara semua aplikasi.

    Kelebihan:

    • UI termasuk terbaik menurut penulis
    • Info resource detail
    • Operasi power VM
    • Bisa tambah instance PBS secara native

    Kekurangan:

    • Sebagian fitur terkunci di premium
    • Tidak ada manajemen snapshot

    4. Proxmate

    Favorit penulis belakangan. Bersih, intuitif, fokus ke monitoring dan operasi cepat. Yang menonjol: bisa lihat kesehatan Ceph langsung dari aplikasi (katanya tidak ada di aplikasi lain), kelola snapshot di versi berbayar, dan SSH quick commands.

    Kelebihan:

    • Mudah dipakai
    • Info paling lengkap di antara semua aplikasi
    • Status kesehatan Ceph native
    • Bisa kelola snapshot
    • Info resource sangat detail
    • Bisa lihat suhu hardware
    • SSH quick commands yang bisa dikustomisasi
    • Operasi power VM
    • Versi premium lisensi seumur hidup, sekitar 9,99 dolar

    Kekurangan:

    • Sebagian fitur perlu versi berbayar

    Jangan lupa, butuh tunnel atau VPN untuk akses dari luar

    Kalau di luar jaringan homelab, jangan pernah ekspos web UI cluster ke internet. Pakai VPN atau tunnel modern seperti Pangolin, Cloudflare Tunnel, atau Twingate. Tidak perlu buka port masuk, cukup izinkan koneksi keluar lewat HTTPS. Alurnya: konek VPN dulu, baru buka aplikasi mobile.

    Tabel perbandingan

    ToolPlatformCocok untukKelebihan utamaKeterbatasan
    Web UI mobile bawaanBrowser (iOS/Android)Akses cluster penuhBawaan Proxmox, fitur cukup, selalu update, tanpa instal aplikasiAda batasan di mobile, tidak semua fitur tersedia
    Aplikasi resmi ProxmoxiOS/AndroidKontrol VM dan node cepatTampilan simpel, operasi power gampangKonfigurasi lanjutan terbatas
    ProxmoboiOS/AndroidDashboard visual yang cantikUI bagus, grafik resource, overview cluster okePihak ketiga, ada batasan fitur
    ProxmateiOS/AndroidMonitoring termasuk CephMonitoring kuat, snapshot, SSH quick action, monitoring hardwareSebagian fitur perlu versi berbayar

    Penutup

    Buat saya ini penemuan yang menyenangkan. Beberapa pendapat saya:

    • HP bukan pengganti web UI desktop, posisinya pelengkap buat monitoring dan tindakan cepat.
    • Mulai dari yang gratis dulu, baru naik ke berbayar kalau butuh fitur seperti snapshot atau monitoring Ceph.
    • Fitur Ceph di Proxmate menarik buat saya yang kebetulan pakai Ceph di cluster sendiri.
    • Sebagus apa pun aplikasinya, keamanan tetap nomor satu. Jangan tergoda kemudahan sampai lupa pakai VPN atau tunnel.

    Referensi