Compile Caddy dari Source #
Secara default, paket installer Caddy yang kita dapatkan melalui package manager (seperti APT di Ubuntu atau COPR di RHEL) maupun image Docker resmi hanya menyertakan modul bawaan (core modules). Modul bawaan ini sudah sangat mencukupi untuk kebutuhan web server umum, seperti reverse proxy standar, pemuatan file statis, kompresi Gzip/Brotli, dan negosiasi sertifikat HTTPS biasa via ACME HTTP/TLS challenge.
Namun, dalam skenario arsitektur produksi yang lebih kompleks, kita sering kali membutuhkan fitur tambahan yang tidak disediakan secara default. Contoh paling umum adalah kebutuhan untuk menerbitkan sertifikat SSL Wildcard (*.situsku.com) yang mewajibkan validasi kepemilikan domain menggunakan DNS-01 challenge. Skenario ini membutuhkan modul DNS provider khusus (seperti Cloudflare, Route53, atau DigitalOcean). Contoh lainnya adalah kebutuhan untuk menambahkan fitur pembatasan akses (rate limiting), autentikasi terpusat (OAuth2/OIDC), atau sistem caching terdistribusi.
Untuk memenuhi kebutuhan ini, Caddy menyediakan mekanisme kompilasi mandiri yang sangat mudah menggunakan utilitas resmi bernama xcaddy. Artikel ini akan memandu kita melakukan kompilasi Caddy dari kode sumber (source code) secara aman dan profesional.
Mengapa Kita Perlu Mengompilasi Caddy Sendiri? #
Mari kita bandingkan ketersediaan fitur antara binary standar resmi dengan kebutuhan plugin kustom:
Binary Resmi Caddy (Langsung Pakai):
✓ http.handlers.reverse_proxy (Proxy balik)
✓ http.handlers.file_server (File statis)
✓ http.handlers.encode (Gzip, Zstd)
✓ http.handlers.basicauth (Autentikasi dasar)
✓ http.handlers.rewrite & redirect
✓ tls.issuance.acme (Let's Encrypt / ZeroSSL)
✓ tls.issuance.internal (Local CA)
Plugin Tambahan (Perlu Kompilasi):
✗ dns.providers.cloudflare → Membaca DNS Cloudflare untuk SSL
✗ dns.providers.route53 → Integrasi AWS Route53
✗ dns.providers.digitalocean → Integrasi DNS DigitalOcean
✗ http.handlers.rate_limit → Pembatasan request per-IP/User
✗ http.handlers.security → Integrasi SSO / OAuth2 / OIDC
✗ http.handlers.cache → Sistem HTTP cache tingkat lanjut
Jika arsitektur kita membutuhkan salah satu dari komponen di kolom kanan, kita wajib melakukan kompilasi mandiri.
Prasyarat: Memasang Compiler Go #
Karena Caddy ditulis menggunakan bahasa pemrograman Go, proses kompilasi membutuhkan kehadiran Go Compiler pada sistem build kita. Caddy selalu membutuhkan versi Go yang relatif baru (minimal Go 1.21 atau versi di atasnya).
[!IMPORTANT] Jangan Lakukan Kompilasi di Server Produksi! Menjalankan Go compiler membutuhkan sumber daya CPU dan memori yang cukup besar. Selain itu, menginstal perkakas development di server produksi memperluas area serangan keamanan (attack surface). Praktik terbaiknya adalah melakukan kompilasi di komputer lokal developer, server build khusus (CI/CD), lalu mengirimkan file binary hasil kompilasi ke server produksi.
Jika kita ingin menyiapkan Go di lingkungan kompilasi kita (misalnya Ubuntu build machine):
# Langkah 1: Bersihkan instalasi Go lama jika ada
sudo rm -rf /usr/local/go
# Langkah 2: Unduh paket Go resmi (sesuaikan versi teranyar)
GO_VER="1.22.4"
wget "https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz"
# Langkah 3: Ekstrak paket ke direktori /usr/local
sudo tar -C /usr/local -xzf "go${GO_VER}.linux-amd64.tar.gz"
# Langkah 4: Daftarkan path Go ke konfigurasi shell kita (~/.bashrc atau ~/.zshrc)
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bashrc
# Langkah 5: Muat ulang konfigurasi shell
source ~/.bashrc
# Langkah 6: Verifikasi bahwa Go compiler telah terpasang dengan benar
go version
# Output diharapkan: go version go1.22.4 linux/amd64
Memasang Utilitas xcaddy
#
Tim developer Caddy membuat xcaddy untuk menyembunyikan kerumitan perintah build Go yang panjang. xcaddy secara otomatis mengunduh kode sumber Caddy sesuai versi yang kita inginkan, mengunduh plugin-plugin yang kita definisikan, menyusun kode inisialisasi, dan mengompilasinya menjadi satu berkas binary utuh.
Kita dapat menginstal xcaddy secara global menggunakan perintah go install:
# Mengunduh dan mengompilasi xcaddy versi terbaru langsung dari repositori resmi
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
Executable xcaddy akan disimpan di direktori $GOPATH/bin (biasanya berada di ~/go/bin). Pastikan kita sudah mendaftarkan path tersebut di variabel lingkungan shell kita (sesuai Langkah 4 di bagian prasyarat).
Kita dapat memverifikasi pemasangan xcaddy dengan:
xcaddy version
# Output contoh: xcaddy v0.4.2
Kompilasi Caddy Menggunakan xcaddy
#
Proses kompilasi dengan xcaddy bersifat sangat modular. Kita dapat menentukan versi Caddy utama yang ingin dibangun serta menyertakan satu atau lebih plugin sekaligus.
1. Build Standar (Tanpa Plugin Tambahan) #
Untuk sekadar memastikan compiler kita bekerja, kita dapat melakukan build Caddy standar:
# Memulai proses build Caddy versi stabil terbaru
xcaddy build
Perintah ini akan menghasilkan file executable bernama caddy di direktori aktif kita saat ini. Kita dapat memeriksa ukurannya dan daftar modul internalnya:
# Memeriksa keberadaan file binary
ls -lh caddy
# Memeriksa versi binary kustom kita
./caddy version
# Menampilkan seluruh modul yang terintegrasi di dalam binary tersebut
./caddy list-modules
2. Build dengan Plugin Cloudflare DNS #
Mari kita bangun Caddy dengan menyertakan modul DNS Cloudflare untuk kebutuhan pengurusan SSL Wildcard:
# Melakukan build Caddy dengan menyertakan plugin cloudflare
xcaddy build \
--with github.com/caddy-dns/cloudflare
Setelah selesai, kita dapat memverifikasi modul DNS tersebut telah aktif:
./caddy list-modules | grep cloudflare
# Output: dns.providers.cloudflare
3. Build dengan Banyak Plugin dan Versi Spesifik #
Untuk kebutuhan produksi, kita sangat disarankan menentukan versi mayor/minor Caddy secara eksplisit agar proses build dapat diulang secara konsisten (reproducible build):
# Membangun Caddy versi v2.8.4 dengan beberapa modul kustom sekaligus
xcaddy build v2.8.4 \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-ratelimit \
--with github.com/caddyserver/cache-handler
Kunci Versi Plugin demi Keamanan Produksi #
Secara default, jika kita tidak menentukan versi plugin saat menjalankan --with, xcaddy akan mencari versi terbaru (latest) dari plugin tersebut di GitHub. Ini adalah perilaku yang kurang aman untuk lingkungan produksi karena perubahan API kode plugin di masa depan dapat merusak build kita secara mendadak.
Kita harus mengunci versi plugin ke tag rilis semver atau commit hash yang spesifik:
# BENAR: Mengunci versi Caddy dan versi masing-masing plugin secara presisi
xcaddy build v2.8.4 \
--with github.com/caddy-dns/[email protected] \
--with github.com/mholt/[email protected]
Kita dapat membungkus perintah build ini ke dalam sebuah shell script sederhana agar tim pengembang kita memiliki dokumentasi build yang konsisten:
# Buka editor untuk membuat script build
nano build-caddy.sh
Isi dengan script berikut:
#!/usr/bin/env bash
# build-caddy.sh
# Script untuk melakukan kompilasi Caddy kustom secara konsisten.
set -euo pipefail
CADDY_VER="v2.8.4"
CLOUDFLARE_VER="v0.0.0-20240101123456-abc1234def56"
RATELIMIT_VER="v0.0.0-20240101234567-def5678abc12"
echo "=== MEMULAI KOMPILASI CADDY ==="
xcaddy build "${CADDY_VER}" \
--with "github.com/caddy-dns/cloudflare@${CLOUDFLARE_VER}" \
--with "github.com/mholt/caddy-ratelimit@${RATELIMIT_VER}"
echo "=== VERIFIKASI HASIL BUILD ==="
./caddy version
./caddy list-modules | grep -E 'cloudflare|rate_limit'
echo "Kompilasi sukses!"
Simpan script tersebut dan ubah permission-nya agar bisa dieksekusi:
chmod +x build-caddy.sh
./build-caddy.sh
Menerapkan Binary Baru ke Server Systemd #
Setelah berhasil mendapatkan file binary caddy kustom dari mesin build kita, langkah berikutnya adalah menggantikan binary Caddy lama di server produksi kita.
Skenario Penggantian Binary APT (Rollback Plan) #
Jika server produksi kita sebelumnya menggunakan instalasi APT (di mana binary default berada di /usr/bin/caddy), ikuti urutan pemeliharaan berikut untuk meminimalkan waktu henti (downtime):
# Langkah 1: Hentikan sementara layanan Caddy
sudo systemctl stop caddy
# Langkah 2: Backup binary lama dengan memberikan penanda tanggal
# Backup ini sangat krusial agar kita bisa melakukan rollback cepat jika binary baru mengalami crash
sudo cp /usr/bin/caddy /usr/bin/caddy.backup.$(date +%Y%m%d)
# Langkah 3: Salin binary kustom baru kita ke direktori /usr/bin/
sudo cp ./caddy /usr/bin/caddy
# Langkah 4: Berikan hak akses eksekusi pada binary baru
sudo chmod +x /usr/bin/caddy
# Langkah 5: Verifikasi versi dan plugin pada path sistem
caddy version
caddy list-modules | grep cloudflare
# Langkah 6: Jalankan kembali layanan Caddy
sudo systemctl start caddy
# Langkah 7: Memeriksa log journalctl untuk memastikan transisi berjalan lancar
sudo journalctl -u caddy -n 20 --no-pager
Jika terjadi masalah fatal saat layanan dijalankan dengan binary baru, kita dapat memulihkan server ke kondisi semula dengan cepat:
# STRATEGI ROLLBACK CEPAT (Jika Terjadi Kegagalan)
sudo cp /usr/bin/caddy.backup.[TANGGAL_BACKUP] /usr/bin/caddy
sudo systemctl start caddy
Integrasi CI/CD Menggunakan GitHub Actions #
Untuk tim berskala besar, mengotomatiskan kompilasi Caddy menggunakan pipeline CI/CD adalah solusi terbaik. Setiap kali kita merilis tag baru, GitHub Actions akan melakukan kompilasi otomatis dan menyimpan hasilnya sebagai artefak rilis.
Kita dapat membuat berkas alur kerja di .github/workflows/build-caddy.yml:
name: Build Custom Caddy
on:
push:
tags:
- 'v*'
workflow_dispatch: # Mengizinkan pemicuan manual dari dashboard GitHub
jobs:
compile:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Setup Go Compiler
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Install xcaddy
run: go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
- name: Compile Caddy Binary
run: |
xcaddy build v2.8.4 \
--with github.com/caddy-dns/[email protected] \
--with github.com/mholt/[email protected]
- name: Upload Binary Artifact
uses: actions/upload-artifact@v4
with:
name: caddy-kustom-linux-amd64
path: ./caddy
Kompilasi untuk Pengembangan Plugin Lokal #
Jika kita sedang mengembangkan plugin Caddy sendiri menggunakan bahasa Go, kita dapat memanfaatkan xcaddy untuk melakukan kompilasi silang dengan mengarahkan modul ke direktori lokal kita.
Misalkan kita memiliki folder proyek plugin kustom kita:
proyek-plugin-kita/
├── go.mod
├── go.sum
└── plugin_kita.go
Kita dapat mengompilasi Caddy dengan menyertakan kode lokal tersebut menggunakan tanda sama dengan (=):
# Memetakan nama paket Go ke direktori fisik lokal kita
xcaddy build \
--with github.com/nama-kita/caddy-plugin-kita=./proyek-plugin-kita
Ini mempermudah proses pembuatan prototipe dan debugging modul Caddy secara real-time sebelum dipublikasikan ke GitHub.
Troubleshooting Kompilasi #
1. Masalah Versi Go: “Requires Go 1.21 or Later” #
Proses kompilasi terhenti karena versi compiler Go di sistem kita terlalu usang. Solusi: Hapus instalasi Go bawaan package manager Linux distro kita (yang biasanya tertinggal beberapa versi) dan instal versi Go termutakhir secara manual dari situs golang.org sesuai panduan di awal artikel ini.
2. xcaddy: Command Not Found #
Shell tidak dapat menemukan perintah xcaddy setelah proses go install.
Solusi:
Pastikan variabel lingkungan GOPATH telah terdaftar dan bin folder-nya telah dimasukkan ke variabel global PATH sistem kita.
# Tambahkan ini ke shell kita
export PATH=$PATH:$(go env GOPATH)/bin
3. Ketidakcocokan Versi Modul (Dependency Conflicts) #
Proses build menghasilkan error kompilasi Go (compile-time error) yang berkaitan dengan ketidakcocokan tipe parameter atau struktur modul.
Solusi:
Hal ini terjadi karena versi plugin yang kita panggil menggunakan API internal Caddy yang berbeda dengan versi Caddy yang kita tentukan. Coba hapus penanda @version spesifik pada plugin untuk menguji kompilasi menggunakan versi latest yang umumnya telah menyesuaikan rilis Caddy stabil terbaru.
Kapan Beralih ke Alternatif / Tidak Menggunakan Ini #
Tetap gunakan Kompilasi xcaddy jika:
✓ Kita memerlukan modul DNS provider untuk validasi SSL Wildcard Let's Encrypt.
✓ Kita ingin men-deploy plugin pihak ketiga untuk keamanan (rate limit, OAuth).
✓ Kita sedang mengembangkan plugin Caddy sendiri secara lokal.
Pertimbangkan metode lain jika:
✗ Kita hanya membutuhkan Caddy untuk web server static standar (Gunakan APT/COPR).
✗ Kita tidak memiliki akses atau keahlian untuk memelihara siklus update binary secara manual.
✗ Kebijakan organisasi mengharuskan pelacakan dependensi paket OS yang ketat secara terintegrasi.
Ringkasan #
- Peran xcaddy — Perkakas resmi yang mempermudah perakitan binary Caddy kustom dengan menyatukan proses unduh kode sumber dan plugin.
- SSL Wildcard — Modul DNS provider wajib dipasang via kompilasi kustom untuk mendukung penerbitan sertifikat SSL wildcard.
- Kunci Versi — Selalu tentukan versi spesifik untuk Caddy dan masing-masing plugin (
@version) guna menjamin konsistensi build produksi.- Strategi Rollback — Selalu lakukan backup binary lama sebelum menimpanya dengan binary baru di server produksi kita.
- CI/CD Build — Gunakan otomatisasi pipeline (seperti GitHub Actions) untuk menghasilkan file binary yang dapat diverifikasi dan aman.
- Isolasi Server — Jangan instal Go Compiler di server produksi. Lakukan build di lingkungan terpisah dan kirim binary matang ke server tujuan.
← Sebelumnya: Docker Compose Berikutnya: Struktur Caddyfile →