xcaddy #
xcaddy adalah tool resmi dari tim Caddy untuk membangun binary Caddy kustom dengan plugin tambahan. Karena Caddy menggunakan pendekatan compile-time plugins (berbeda dari runtime plugins seperti Nginx), kamu perlu men-compile ulang Caddy setiap kali ingin menambahkan plugin baru.
xcaddy membuat proses ini sangat mudah — satu perintah cukup untuk mengunduh kode plugin, mengkompilasi, dan menghasilkan binary siap pakai.
Mengapa Compile-Time Plugins? #
Runtime plugins (Nginx, Apache):
+ Tidak perlu compile ulang saat tambah plugin
+ Bisa disable/enable plugin tanpa restart
- Plugin berjalan sebagai proses/library terpisah
- Overhead inter-process communication
- ABI compatibility issues antar versi
- Plugin yang buruk bisa crash server
Compile-time plugins (Caddy):
+ Single binary — tidak ada dependency eksternal
+ Plugin terintegrasi penuh, tidak ada overhead IPC
+ Type safety — compiler mendeteksi error lebih awal
+ Binary reproducible dan mudah didistribusikan
- Perlu compile ulang untuk tambah/hapus plugin
- Build process butuh Go toolchain
Instalasi xcaddy #
# Cara 1: Via go install (memerlukan Go terinstall)
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
# Verifikasi instalasi
xcaddy version
# Output: xcaddy v0.4.x go1.22.x linux/amd64
# Cara 2: Download binary langsung
# https://github.com/caddyserver/xcaddy/releases
# Cara 3: Via package manager (beberapa distro)
# sudo apt install xcaddy # Jika tersedia di repo
# Pastikan Go terinstall (minimal Go 1.21)
go version
Build Caddy dengan Satu Plugin #
# Format dasar
xcaddy build [versi_caddy] --with [nama_plugin]
# Build Caddy terbaru dengan satu plugin
xcaddy build --with github.com/caddy-dns/cloudflare
# Build versi spesifik Caddy
xcaddy build v2.8.4 --with github.com/caddy-dns/cloudflare
# Output: binary 'caddy' di direktori saat ini
ls -lh caddy
# -rwxr-xr-x 1 user user 35M Jan 15 14:30 caddy
# Verifikasi plugin tersedia
./caddy list-modules | grep cloudflare
# dns.providers.cloudflare
Build dengan Banyak Plugin #
# Build dengan multiple plugin sekaligus
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 semua plugin tersedia
./caddy list-modules | grep -E "cloudflare|rate_limit|cache|security"
Menentukan Versi Plugin #
# Plugin versi spesifik (menggunakan Go module version)
xcaddy build \
--with github.com/caddy-dns/[email protected] \
--with github.com/mholt/[email protected]
# Plugin dari branch tertentu
xcaddy build \
--with github.com/example/caddy-plugin@main
# Plugin dari commit hash spesifik
xcaddy build \
--with github.com/example/caddy-plugin@abc123def456
# Plugin dari local directory (untuk development)
xcaddy build \
--with github.com/example/caddy-plugin=/path/to/local/plugin
Mengganti Binary yang Ada #
# Build binary baru
xcaddy build v2.8.4 \
--with github.com/caddy-dns/cloudflare
# Stop Caddy sementara
sudo systemctl stop caddy
# Backup binary lama
sudo cp /usr/bin/caddy /usr/bin/caddy.bak
# Ganti dengan binary baru
sudo cp caddy /usr/bin/caddy
sudo chmod +x /usr/bin/caddy
# Verifikasi
caddy version
caddy list-modules | grep cloudflare
# Start Caddy kembali
sudo systemctl start caddy
Zero-Downtime Upgrade dengan caddy upgrade
#
# Caddy punya built-in upgrade command
# tapi tidak support custom plugins
# Untuk upgrade dengan custom plugins, prosesnya:
# 1. Build binary baru dengan xcaddy
xcaddy build v2.8.4 \
--with github.com/caddy-dns/cloudflare
# 2. Validasi config dengan binary baru
./caddy validate --config /etc/caddy/Caddyfile
# 3. Ganti binary (Caddy support graceful restart dengan SIGUSR1)
sudo systemctl stop caddy
sudo cp caddy /usr/bin/caddy
sudo systemctl start caddy
Docker Multi-Stage Build dengan xcaddy #
# Dockerfile
FROM caddy:2.8.4-builder AS builder
# Build Caddy dengan plugin yang diinginkan
RUN xcaddy build \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-ratelimit
# Stage final: hanya binary yang diperlukan
FROM caddy:2.8.4
# Copy binary kustom ke image
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
# Copy konfigurasi
COPY Caddyfile /etc/caddy/Caddyfile
# Build image
docker build -t my-caddy:latest .
# Verifikasi plugin di container
docker run --rm my-caddy:latest caddy list-modules | grep cloudflare
Build di CI/CD Pipeline #
# GitHub Actions workflow untuk build Caddy dengan plugins
name: Build Custom Caddy
on:
push:
branches: [main]
workflow_dispatch:
inputs:
caddy_version:
description: 'Caddy version'
default: 'latest'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Install xcaddy
run: go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
- name: Build Caddy with plugins
run: |
xcaddy build ${{ github.event.inputs.caddy_version || 'latest' }} \
--with github.com/caddy-dns/cloudflare \
--with github.com/mholt/caddy-ratelimit \
--output ./caddy-custom
- name: Test binary
run: |
./caddy-custom version
./caddy-custom list-modules | grep -E "cloudflare|rate_limit"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: caddy-custom-linux-amd64
path: ./caddy-custom
Cross-Compilation #
# Build untuk platform berbeda
# Linux ARM64 (untuk Raspberry Pi, AWS Graviton, dll.)
GOOS=linux GOARCH=arm64 xcaddy build \
--with github.com/caddy-dns/cloudflare
# Linux AMD64
GOOS=linux GOARCH=amd64 xcaddy build \
--with github.com/caddy-dns/cloudflare
# macOS Apple Silicon
GOOS=darwin GOARCH=arm64 xcaddy build \
--with github.com/caddy-dns/cloudflare
# Windows
GOOS=windows GOARCH=amd64 xcaddy build \
--with github.com/caddy-dns/cloudflare
Troubleshooting Build Issues #
# Error: "module not found"
# Pastikan module path benar (cek GitHub repo)
go list -m github.com/caddy-dns/cloudflare@latest
# Error: Go version tidak kompatibel
# Install Go versi terbaru
# https://go.dev/dl/
# Error: build gagal karena dependency conflict
# Coba build dengan versi plugin yang lebih lama
xcaddy build --with github.com/example/[email protected]
# Lihat output build yang detail
XCADDY_DEBUG=1 xcaddy build --with github.com/caddy-dns/cloudflare
# Cache Go module untuk build yang lebih cepat
export GOMODCACHE=/tmp/go-modules
xcaddy build ...
Ringkasan #
xcaddy build --with [plugin]adalah cara standar untuk menambahkan plugin ke Caddy — satu perintah mengunduh, kompilasi, dan menghasilkan binary siap pakai.- Gunakan Docker multi-stage build dengan
caddy:builderimage untuk build yang reproducible dan isolated tanpa perlu install Go di host.- Selalu backup binary lama sebelum mengganti —
cp /usr/bin/caddy /usr/bin/caddy.bakmemungkinkan rollback instan jika ada masalah.- Untuk production, integrasikan xcaddy di CI/CD pipeline agar setiap update Caddy atau plugin menghasilkan binary yang sudah ditest.
- Pin versi plugin yang digunakan (
--with [email protected]) untuk build yang reproducible dan mencegah breaking changes dari plugin update.- Gunakan
caddy list-modulesuntuk memverifikasi plugin berhasil terkompilasi ke dalam binary sebelum deploy ke production.
← Sebelumnya: Log Output Berikutnya: Plugin Populer →
Menjaga Binary Tetap Up-to-date #
Salah satu tantangan dengan compiled plugins adalah mengelola update. Buat script sederhana untuk memudahkan proses update:
#!/bin/bash
# update-caddy.sh — Script untuk update Caddy dengan plugins yang sama
# Daftar plugins yang digunakan
PLUGINS=(
"github.com/caddy-dns/cloudflare"
"github.com/mholt/caddy-ratelimit"
)
# Build string --with untuk xcaddy
WITH_FLAGS=""
for plugin in "${PLUGINS[@]}"; do
WITH_FLAGS="$WITH_FLAGS --with $plugin"
done
echo "Building Caddy with plugins..."
echo "Plugins: ${PLUGINS[*]}"
# Build binary baru
eval "xcaddy build latest $WITH_FLAGS --output /tmp/caddy-new"
# Verifikasi
echo ""
echo "New binary info:"
/tmp/caddy-new version
echo ""
echo "Modules:"
/tmp/caddy-new list-modules | grep -v "^standard"
# Konfirmasi sebelum deploy
read -p "Deploy? (y/N) " confirm
if [ "$confirm" = "y" ]; then
sudo systemctl stop caddy
sudo cp /tmp/caddy-new /usr/bin/caddy
sudo systemctl start caddy
echo "✓ Caddy updated successfully"
else
echo "Deployment cancelled"
fi
xcaddy dengan Private Repository #
# Jika plugin ada di private repo (GitHub, GitLab, Bitbucket)
# Setup SSH atau token terlebih dahulu
# Untuk GitHub private repo dengan token
git config --global url."https://[email protected]/".insteadOf "https://github.com/"
# Build dengan private plugin
xcaddy build \
--with github.com/company/private-caddy-plugin
# Environment variable GONOSUMCHECK jika perlu skip sum check
GONOSUMCHECK="github.com/company/*" xcaddy build \
--with github.com/company/private-caddy-plugin