xcaddy #
xcaddy adalah perangkat lunak baris perintah (command-line tool) resmi yang dikembangkan oleh tim Caddy untuk mempermudah proses pembuatan (build) biner Caddy kustom yang dilengkapi dengan modul atau plugin tambahan. Caddy dirancang dengan arsitektur modular yang sangat fleksibel di mana hampir setiap fitur—mulai dari penanganan protokol HTTP, penyediaan sertifikat DNS challenge, hingga sistem penyimpanan data—berjalan sebagai modul independen. Namun, berbeda dari beberapa server web tradisional yang memuat modul secara dinamis dari berkas pustaka luar saat aplikasi berjalan (runtime plugins), Caddy menggunakan pendekatan modul terkompilasi sejak awal (compile-time plugins). Hal ini mengharuskan kita untuk melakukan kompilasi ulang kode sumber Caddy bersama dengan kode sumber plugin setiap kali kita ingin menambah atau menghapus suatu fitur. xcaddy hadir untuk menyederhanakan proses kompilasi yang kompleks ini menjadi satu perintah baris yang sederhana dengan mengotomatiskan penanganan dependensi Go modules di belakang layar. Kita akan mengupas tuntas keunggulan arsitektur modul terkompilasi, mempelajari cara instalasi xcaddy, mempraktikkan proses pembuatan biner kustom untuk satu atau banyak plugin, melakukan manajemen versi secara presisi, menyusun alur kerja Docker multi-stage build, mengintegrasikannya ke dalam CI/CD pipeline, hingga melakukan kompilasi silang (cross-compilation) untuk berbagai arsitektur perangkat keras.
Konsep Arsitektur: Compile-Time vs Runtime Plugins #
Untuk memahami mengapa kita memerlukan perangkat seperti xcaddy, kita harus terlebih dahulu memahami perbandingan mendasar antara modul yang dimuat pada saat aplikasi berjalan (runtime/dynamic plugins) dengan modul yang digabungkan pada saat kompilasi (compile-time/static plugins).
Beberapa server web populer lainnya menggunakan arsitektur dynamic plugins. Keunggulannya adalah pengguna dapat menginstal atau menonaktifkan modul dengan menyunting berkas konfigurasi teks biasa tanpa menyentuh binar utama server web. Namun, pendekatan ini memiliki konsekuensi teknis yang cukup berat:
- ABI Compatibility: Modul dinamis harus dikompilasi menggunakan versi compiler yang persis sama dengan biner utama server web. Jika ada perbedaan minor pada compiler, modul akan menolak dimuat (Application Binary Interface mismatch).
- Kinerja (Overhead): Komunikasi antar modul dinamis di memori RAM sering kali membutuhkan lapisan jembatan (IPC / Inter-Process Communication) yang dapat menambah latensi mikro pada setiap penanganan request HTTP.
- Stabilitas: Kesalahan alokasi memori (segfault) pada satu modul dinamis yang buruk dapat langsung meruntuhkan stabilitas seluruh proses biner utama server web.
Caddy memilih pendekatan compile-time plugins yang didukung secara native oleh bahasa pemrograman Go. Dalam arsitektur ini, seluruh kode sumber plugin pihak ketiga disatukan secara langsung ke dalam basis kode Caddy sebelum compiler Go membuat berkas biner akhir. Pendekatan ini memberikan beberapa keuntungan luar biasa:
- Biner Tunggal Mandiri (Single Self-Contained Binary): Hasil akhir kompilasi adalah satu berkas biner tunggal tanpa ketergantungan (dependency) pada berkas pustaka luar (
.sodi Linux atau.dlldi Windows). Kita hanya perlu memindahkan satu berkas biner ini untuk men-deploy server Caddy ke mesin target. - Keamanan Tipe Data (Type Safety): Compiler Go akan memeriksa seluruh ketergantungan kode dan tipe data sejak awal. Jika ada ketidakcocokan versi API antara Caddy dengan plugin, proses kompilasi akan langsung gagal di awal, sehingga mencegah terjadinya crash runtime yang tidak terduga di lingkungan produksi.
- Performa Maksimal: Komunikasi antar modul terjadi secara langsung sebagai pemanggilan fungsi native Go di dalam memori terisolasi yang sama. Hal ini meniadakan latensi overhead komunikasi eksternal.
Kelemahan utama dari pendekatan ini adalah setiap kali kita ingin memperbarui atau menambah plugin baru, kita harus melakukan proses kompilasi ulang. Di sinilah xcaddy memainkan peran krusial dengan mengotomatiskan seluruh alur kerja penulisan kode pembungkus (glue code) Go dan pemanggilan compiler Go untuk kita.
Instalasi xcaddy #
Sebelum dapat menggunakan xcaddy, kita harus menginstalnya terlebih dahulu pada mesin pengembangan kita. Karena xcaddy bertugas memicu kompilasi kode Go, mesin kita wajib memiliki instalasi Go compiler (Go SDK) aktif dengan versi minimal yang sesuai dengan persyaratan Caddy (direkomendasikan versi Go 1.21 ke atas).
Berikut adalah tiga metode instalasi xcaddy yang dapat kita pilih:
Metode 1: Instalasi Melalui go install (Direkomendasikan)
#
Jika mesin kita sudah memiliki Go SDK yang terinstal, ini adalah metode tercepat dan paling bersih untuk mengunduh dan mengompilasi biner xcaddy terbaru langsung dari repositori resminya:
# Mengompilasi dan menginstal xcaddy ke direktori $GOPATH/bin atau $HOME/go/bin kita
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
# Pastikan direktori bin Go sudah masuk ke dalam PATH sistem kita, lalu verifikasi instalasi:
xcaddy version
# Contoh output: xcaddy v0.4.1 go1.22.4 darwin/arm64
Metode 2: Menggunakan Manajer Paket Sistem (Package Manager) #
Jika kita lebih menyukai manajemen paket otomatis melalui sistem operasi, beberapa distribusi menyediakan repositori kustom untuk xcaddy:
- Untuk macOS (Menggunakan Homebrew):
brew install xcaddy - Untuk Debian/Ubuntu (Menggunakan Repositori Resmi Caddy):
# Tambahkan repositori resmi Caddy jika belum terinstal sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-xcaddy-archive-keyring.gpg curl -1sLf 'https://dl.cloudsmith.io/public/caddy/xcaddy/config.deb.txt?term=exact' | sudo tee /etc/apt/sources.list.d/caddy-xcaddy.list sudo apt update sudo apt install xcaddy
Metode 3: Mengunduh Biner Pra-Kompilasi Secara Langsung #
Jika kita tidak ingin menginstal Go SDK atau package manager di komputer kita (misalnya saat kita hanya ingin mengunduh biner secara instan), kita dapat mengunduh berkas arsip biner xcaddy secara manual dari halaman rilis GitHub resmi: xcaddy Releases. Ekstrak berkas arsip tersebut dan pindahkan biner xcaddy ke dalam folder PATH sistem kita (seperti /usr/local/bin).
Kompilasi Caddy Menggunakan xcaddy #
Setelah xcaddy terpasang dan Go compiler dapat diakses oleh sistem, kita siap melakukan pembuatan biner Caddy kustom.
1. Membuat Biner Default (Tanpa Plugin Tambahan) #
Untuk sekadar memastikan bahwa sistem kompilasi kita bekerja dengan baik, kita dapat menjalankan perintah build tanpa parameter apa pun. Perintah ini akan mengunduh kode sumber Caddy rilis stabil terbaru dan mengompilasinya menjadi berkas biner bernama caddy di direktori aktif kita:
# Menjalankan kompilasi default
xcaddy build
2. Membuat Biner dengan Satu Plugin Tambahan #
Skenario yang paling sering dihadapi adalah kebutuhan untuk menambahkan modul provider DNS challenge (misalnya Cloudflare) agar Caddy dapat mengajukan sertifikat SSL wildcard. Kita menggunakan opsi --with diikuti oleh nama modul repositori plugin Go:
# Kompilasi Caddy terbaru dengan plugin DNS Cloudflare
xcaddy build --with github.com/caddy-dns/cloudflare
# Periksa hasil kompilasi berkas biner di direktori aktif
ls -lh caddy
# -rwxr-xr-x 1 user staff 38M Jun 16 18:47 caddy
# Lakukan verifikasi apakah modul cloudflare sudah terintegrasi ke dalam biner baru
./caddy list-modules | grep dns.providers.cloudflare
# Output konfirmasi: dns.providers.cloudflare
3. Membuat Biner dengan Banyak Plugin Sekaligus #
Kita tidak dibatasi hanya pada satu opsi --with. Kita dapat menambahkan parameter --with sebanyak yang kita butuhkan untuk menggabungkan berbagai macam plugin ke dalam satu biner Caddy tunggal:
# Kompilasi Caddy dengan kombinasi empat plugin pihak ketiga populer
xcaddy build \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-ratelimit \
--with github.com/caddyserver/cache-handler \
--with github.com/greenpau/caddy-security
# Verifikasi keberadaan semua modul terkompilasi dalam satu perintah
./caddy list-modules | grep -E "cloudflare|rate_limit|cache|security"
Manajemen Versi Plugin secara Presisi #
Secara default, jika kita tidak menentukan versi, xcaddy akan mengambil versi tag rilis stabil terbaru (@latest) dari Caddy dan masing-masing plugin yang kita deklarasikan. Namun, pada lingkungan produksi yang membutuhkan stabilitas tingkat tinggi, kita wajib menetapkan versi secara presisi guna menghindari kegagalan kompilasi atau perubahan perilaku biner secara tiba-tiba akibat pembaruan kode plugin yang merusak kompatibilitas (breaking changes).
xcaddy mendukung beberapa sintaks penentuan versi yang fleksibel:
1. Menentukan Versi Spesifik Caddy dan Plugin #
Kita dapat menambahkan penanda versi tag semantik (@vX.Y.Z) baik pada argumen versi Caddy utama maupun pada argumen nama repositori plugin:
# Kompilasi Caddy versi 2.8.4 dengan plugin Cloudflare versi 0.0.8
xcaddy build v2.8.4 \
--with github.com/caddy-dns/[email protected]
2. Kompilasi Menggunakan Branch atau Commit Hash Tertentu #
Jika kita membutuhkan fitur terbaru dari plugin yang belum dirilis secara resmi dalam bentuk tag, kita dapat merujuk langsung ke nama branch atau ID commit hash repositori Git:
# Merujuk ke branch utama (main/master)
xcaddy build --with github.com/example/caddy-plugin@main
# Merujuk ke commit hash spesifik (SHA-1 12 karakter) untuk keamanan deterministik
xcaddy build --with github.com/example/caddy-plugin@abc123def456
3. Mengganti dengan Kode Sumber Lokal (Local Development Module) #
Jika kita adalah seorang pengembang plugin Caddy yang sedang menulis kode modul kustom di komputer lokal, kita dapat menginstruksikan xcaddy untuk mengganti path modul repositori online dengan path direktori lokal kita. Ini membolehkan kita menguji modul buatan kita secara real-time tanpa perlu mengunggah kode ke GitHub terlebih dahulu:
# Format: --with <import_path>=<local_path>
xcaddy build \
--with github.com/user/my-custom-plugin=/Users/user/Projects/my-custom-plugin
Langkah Graceful Upgrade Biner di Produksi #
Salah satu tantangan operasional terbesar di server produksi adalah bagaimana cara memperbarui atau mengganti biner server web yang sedang aktif tanpa menghentikan layanan penanganan request pengguna (zero-downtime upgrade).
Kita dilarang keras untuk langsung menimpa berkas biner Caddy aktif secara kasar (misalnya menimpa /usr/bin/caddy saat proses Caddy sedang berjalan). Hal ini akan memicu filesystem text file busy error dan berisiko merusak memori proses server web kita.
Berikut adalah panduan langkah-langkah aman (graceful upgrade) untuk mengganti biner Caddy di server Linux produksi:
Langkah 1: Lakukan Kompilasi Biner Baru #
Lakukan proses kompilasi biner kustom menggunakan xcaddy di direktori terisolasi atau di mesin staging kita:
xcaddy build v2.8.4 --with github.com/caddy-dns/cloudflare
Langkah 2: Validasi Berkas Konfigurasi Menggunakan Biner Baru #
Sebelum mengganti biner sistem, kita harus memastikan bahwa biner baru yang kita buat dapat membaca berkas konfigurasi Caddyfile produksi kita tanpa memicu error parsing:
# Memvalidasi Caddyfile menggunakan biner kustom lokal baru
./caddy validate --config /etc/caddy/Caddyfile
# Pastikan output menampilkan: "Valid configuration"
Langkah 3: Backup Biner Lama Server #
Pencadangan adalah langkah pertahanan terbaik. Jika terjadi kejanggalan performa setelah upgrade, kita dapat melakukan rollback instan dalam hitungan detik:
# Backup biner aktif
sudo cp /usr/bin/caddy /usr/bin/caddy.bak
Langkah 4: Timpa Berkas Biner dengan Aman #
Lakukan penyalinan biner baru dengan menimpa biner di direktori sistem. Untuk meminimalkan risiko kunci sistem berkas Linux, gunakan perintah pemindahan (mv) atau penyalinan paksa (cp dengan opsi overwrite):
# Pindahkan biner baru ke direktori bin sistem
sudo cp caddy /usr/bin/caddy
# Berikan hak akses eksekusi yang benar
sudo chmod +x /usr/bin/caddy
Langkah 5: Picu Reload Konfigurasi secara Graceful #
Caddy memiliki arsitektur port sharing canggih di mana instansi baru dapat berjalan dan mengikat socket port jaringan (seperti port 80 dan 443) secara paralel sebelum instansi lama menutup koneksinya. Hal ini dilakukan melalui sinyal internal reload:
# Jika kita menggunakan systemd, jalankan reload service
sudo systemctl reload caddy
# Atau picu reload langsung melalui biner
caddy reload --config /etc/caddy/Caddyfile
Systemd akan mengirimkan sinyal SIGUSR1 ke proses master Caddy lama. Caddy lama akan menyerahkan socket TCP ke proses baru secara aman di latar belakang, membiarkan koneksi pengguna yang ada selesai diproses (draining connections), lalu menghentikan dirinya sendiri secara otomatis tanpa menjatuhkan satu pun request HTTP baru pengguna.
Docker Multi-Stage Build dengan xcaddy #
Menginstal Go SDK dan xcaddy langsung di dalam server produksi atau mesin deployment virtual machine (VM) kita sering kali dinilai kurang aman dan membebani ruang penyimpanan sistem. Pendekatan terbaik untuk menjaga kebersihan sistem adalah dengan menggunakan wadah kontainer Docker terisolasi melalui fitur Multi-Stage Build.
Tim pengembang Caddy menyediakan Docker image khusus builder bernama caddy:builder yang sudah dilengkapi dengan instalasi Go compiler dan tool xcaddy siap pakai. Kita dapat menyusun Dockerfile kustom sebagai berikut:
# Stage 1: Pipa Kompilasi terisolasi menggunakan image builder resmi
FROM caddy:2.8.4-builder AS builder
# Tentukan versi Caddy dan pasang plugin yang dibutuhkan
RUN xcaddy build \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-ratelimit
# Stage 2: Membuat image final yang bersih dan minimalis
FROM caddy:2.8.4-alpine
# Salin hanya biner Caddy hasil kompilasi kustom dari Stage 1
# Tindakan ini menimpa biner Caddy default di image alpine
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
# Ekspos port standar web
EXPOSE 80 443 2019
# Caddy akan otomatis berjalan menggunakan biner kustom baru kita
Dengan struktur Dockerfile di atas, hasil akhir image Docker kita tetap berukuran kecil (~40 Megabyte) karena Go compiler dan dependensi kode sumber yang berukuran ratusan megabyte tertinggal secara permanen di Stage 1 yang diabaikan.
Build di CI/CD Pipeline (GitHub Actions) #
Untuk menjamin reproduksibilitas biner kustom dan mempermudah kolaborasi tim developer, kita sebaiknya mengotomatiskan proses kompilasi Caddy menggunakan CI/CD pipeline seperti GitHub Actions. Setiap kali kita mengubah daftar plugin di konfigurasi repositori kita, GitHub Actions akan melakukan kompilasi otomatis dan menyediakan berkas biner kustom siap unduh.
Berikut adalah berkas konfigurasi GitHub Actions .github/workflows/build-caddy.yml yang sangat andal dan direkomendasikan:
name: Build Custom Caddy Binary
on:
push:
branches: [ main ]
workflow_dispatch: # Memungkinkan pemicuan manual dari dashboard GitHub
jobs:
build-caddy:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up Go SDK Environment
uses: actions/setup-go@v5
with:
go-version: '1.22'
cache: true # Mengaktifkan caching otomatis untuk Go modules build cache
- name: Install xcaddy Utility
run: go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
- name: Compile Caddy with Custom Plugins
run: |
xcaddy build latest \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-ratelimit \
--output ./caddy-production
- name: Verify Compiled Modules
run: |
chmod +x ./caddy-production
./caddy-production version
./caddy-production list-modules | grep -E "cloudflare|rate_limit"
- name: Upload Binary Artifact
uses: actions/upload-artifact@v4
with:
name: caddy-custom-linux-amd64
path: ./caddy-production
retention-days: 7
Cross-Compilation dan Akses Repositori Privat #
Caddy dan Go compiler mendukung kemampuan kompilasi silang (cross-compilation) yang luar biasa secara bawaan. Kita dapat melakukan kompilasi biner kustom untuk sistem operasi dan arsitektur perangkat keras yang berbeda langsung dari komputer lokal kita hanya dengan mendefinisikan variabel lingkungan (GOOS dan GOARCH).
1. Perintah Kompilasi Silang Populer #
# Membuat biner untuk Linux ARM64 (misalnya untuk AWS Graviton atau Raspberry Pi)
GOOS=linux GOARCH=arm64 xcaddy build --with github.com/caddy-dns/cloudflare
# Membuat biner untuk Windows AMD64 (menghasilkan berkas caddy.exe)
GOOS=windows GOARCH=amd64 xcaddy build --with github.com/caddy-dns/cloudflare
# Membuat biner untuk macOS Apple Silicon (M1/M2/M3) dari mesin Linux
GOOS=darwin GOARCH=arm64 xcaddy build --with github.com/caddy-dns/cloudflare
2. Kompilasi Menggunakan Repositori Plugin Privat #
Ketika tim internal perusahaan kita mengembangkan plugin Caddy khusus yang bersifat rahasia dan disimpan di dalam repositori privat GitHub atau GitLab, perintah xcaddy secara bawaan akan gagal karena Go compiler tidak dapat mengunduh kode privat tersebut tanpa otentikasi.
Untuk mengatasi hambatan ini, kita harus mengonfigurasi Git kredensial lokal kita dan mendefinisikan beberapa variabel lingkungan khusus Go:
# 1. Konfigurasi Git untuk mengubah skema URL HTTPS menjadi SSH (atau gunakan token HTTPS)
# Ini memaksa Git menggunakan kunci SSH lokal kita untuk otentikasi unduhan privat
git config --global url."[email protected]:".insteadOf "https://github.com/"
# 2. Definisikan variabel lingkungan GOPRIVATE dan GONOSUMCHECK.
# GOPRIVATE menginstruksikan Go untuk tidak mengunduh modul privat melewati server proxy publik Go.
# GONOSUMCHECK menginstruksikan Go untuk tidak memeriksa hash checksum modul privat ke database sum.golang.org publik.
export GOPRIVATE="github.com/my-company/*"
export GONOSUMCHECK="github.com/my-company/*"
# 3. Jalankan kompilasi seperti biasa
xcaddy build --with github.com/my-company/private-caddy-plugin
Troubleshooting Masalah Kompilasi #
Meskipun xcaddy dirancang untuk mempermudah proses pembuatan biner, kita terkadang dapat menemui kendala teknis akibat dependensi kode. Berikut adalah beberapa masalah umum beserta solusinya:
1. Masalah: “Module Not Found” atau “Go Get Error” #
- Penyebab: Jalur import plugin yang kita masukkan tidak valid, atau repositori plugin tersebut telah dipindahkan/dihapus oleh pembuatnya.
- Solusi: Periksa kembali URL repositori plugin di halaman GitHub pembuatnya. Pastikan modul tersebut mendukung kompatibilitas versi Go module yang benar.
2. Masalah: Kegagalan Resolusi Dependensi (Dependency Conflict) #
- Penyebab: Terjadi konflik versi paket pustaka Go yang digunakan secara bersamaan oleh Caddy dengan plugin. Misalnya, Caddy menggunakan paket
foo v2.0sedangkan plugin kustom kita memaksa penggunaanfoo v1.0. - Solusi: Pin plugin kustom kita ke versi tag lama yang kompatibel, atau lakukan pembaruan kode dependensi di dalam proyek plugin kustom kita agar sejajar dengan versi modul Go yang digunakan oleh basis kode Caddy terbaru.
- Kita dapat memicu mode debug terperinci untuk melacak letak konflik dengan mendefinisikan variabel debug:
XCADDY_DEBUG=1 xcaddy build --with github.com/example/plugin
Diagram Pipa Pemrosesan Kompilasi xcaddy #
Untuk mempermudah pemahaman kita mengenai urutan langkah logis yang dikerjakan oleh utilitas xcaddy dan Go compiler di belakang layar, mari kita perhatikan diagram flowchart di bawah ini:
flowchart TD
A["1. Perintah xcaddy Pemicu Mulai\n(e.g., xcaddy build --with plugin)"] --> B["2. Verifikasi Lingkungan Lokal\n(Periksa instalasi Go SDK di PATH)"]
B --> C{"3. Apakah Go SDK tersedia?"}
C -- "Tidak" --> D["Keluar dengan Error:\n'Go compiler not found'"]
C -- "Ya" --> E["4. Buat Direktori Kerja Sementara\n(Direktori temporary di memori RAM/Disk)"]
E --> F["5. Susun Glue Code Go Kustom\n(Mengimpor basis Caddy & mendaftarkan modul plugin)"]
F --> G["6. Jalankan Resolusi Dependensi Go Modules\n(go get & download source code dependencies)"]
G --> H{"7. Apakah resolusi sukses?"}
H -- "Tidak" --> I["Keluar dengan Error:\n'Dependency Conflict'"]
H -- "Ya" --> J["8. Picu Go Compiler build\n(Menghasilkan biner mesin lokal teroptimasi)"]
J --> K{"9. Apakah kompilasi sukses?"}
K -- "Tidak" --> L["Keluar dengan Error:\n'Compilation failed'"]
K -- "Ya" --> M["10. Pindahkan berkas biner kustom ke direktori aktif"]
M --> N["11. Hapus Direktori Sementara\n(Pembersihan sisa cache build)"]
N --> O["12. Proses Pembuatan Biner Selesai"]Ringkasan #
- Modul Terkompilasi: Caddy menggunakan modul compile-time demi mencapai performa maksimal, portabilitas biner tunggal mandiri, dan tingkat keamanan tipe data tinggi.
- Fungsi Utama xcaddy:
xcaddyadalah jembatan otomatisasi untuk mengunduh, mengonfigurasi glue code, dan mengompilasi plugin pihak ketiga ke dalam biner Caddy.- Kebutuhan Go SDK: Mesin pengembangan wajib memiliki Go compiler terinstal untuk menjalankan perintah
xcaddy buildlokal secara sukses.- Manajemen Kredensial: Selalu pin versi plugin kustom (
--with [email protected]) pada lingkungan produksi demi menjamin stabilitas biner jangka panjang.- Zero-Downtime Upgrade: Gunakan sinyal reload (
systemctl reload caddy) setelah melakukan pemindahan biner baru untuk transisi proses server tanpa interupsi request klien.- Kebersihan Cloud-Native: Terapkan Docker Multi-Stage Build menggunakan base image
caddy:builderuntuk merakit biner kustom tanpa mengotori image produksi final.- Kompilasi Silang: Kita dapat membuat biner Caddy kustom untuk platform Linux ARM64 atau Windows secara instan dengan mendefinisikan variabel
GOOSdanGOARCH.- Akses Repositori Privat: Konfigurasi SSH Git URL replacement dipadukan dengan variabel
GOPRIVATEuntuk membolehkanxcaddymemuat kode plugin privat.