Caddy Validate #
caddy validate adalah perintah yang memvalidasi file konfigurasi Caddy tanpa menjalankan server. Ini adalah alat yang sangat penting untuk workflow deployment yang aman — selalu validasi sebelum reload atau deploy ke production.
Cara Kerja caddy validate
#
caddy validate --config /etc/caddy/Caddyfile
Proses validasi:
1. Parse Caddyfile → JSON internal
2. Cek syntax (apakah semua directive valid?)
3. Cek semantic (apakah nilai-nilai masuk akal?)
4. Provision modul secara dry-run
(jalankan Provision() tapi tidak start server)
5. Jalankan Validate() pada semua modul
Hasil:
VALID → Print "Valid configuration", exit code 0
INVALID → Print error detail, exit code 1
Penggunaan Dasar #
# Validasi Caddyfile default (/etc/caddy/Caddyfile)
caddy validate
# Validasi file tertentu
caddy validate --config /etc/caddy/Caddyfile
# Validasi JSON config
caddy validate --config /etc/caddy/config.json --adapter json
# Validasi dari stdin
cat /etc/caddy/Caddyfile | caddy validate --config /dev/stdin
# Validasi dan cetak konfigurasi JSON yang dihasilkan
caddy validate --config /etc/caddy/Caddyfile && \
caddy adapt --config /etc/caddy/Caddyfile | jq .
Output Validasi #
# Sukses:
$ caddy validate --config /etc/caddy/Caddyfile
Valid configuration
# Gagal (contoh 1 — syntax error):
$ caddy validate --config /etc/caddy/Caddyfile
parsing Caddyfile tokens: /etc/caddy/Caddyfile:5 - Error during parsing:
unrecognized directive: rverse_proxy
# Gagal (contoh 2 — modul tidak ditemukan):
$ caddy validate --config /etc/caddy/Caddyfile
loading initial config: loading new config: http app module:
provisioning http handlers: handler module "dns" not registered
# Gagal (contoh 3 — nilai tidak valid):
$ caddy validate --config /etc/caddy/Caddyfile
loading initial config: loading new config: tls app:
invalid ACME CA URL: ...
# Cek exit code untuk scripting
caddy validate --config /etc/caddy/Caddyfile
echo "Exit code: $?" # 0 = valid, 1 = invalid
Integrasi di Pre-Deploy Script #
#!/bin/bash
# deploy.sh — Safe deployment dengan validation
set -e # Exit on any error
CONFIG_FILE="/etc/caddy/Caddyfile"
NEW_CONFIG="$1" # Path ke config baru
if [ -z "$NEW_CONFIG" ]; then
echo "Usage: $0 <new-config-file>"
exit 1
fi
echo "[1/4] Validating new configuration..."
if ! caddy validate --config "$NEW_CONFIG"; then
echo "✗ Configuration validation FAILED"
echo " Deployment aborted. Current config is unchanged."
exit 1
fi
echo "✓ Configuration is valid"
echo "[2/4] Backing up current configuration..."
BACKUP="/etc/caddy/Caddyfile.bak.$(date +%Y%m%d_%H%M%S)"
cp "$CONFIG_FILE" "$BACKUP"
echo "✓ Backup saved to $BACKUP"
echo "[3/4] Applying new configuration..."
cp "$NEW_CONFIG" "$CONFIG_FILE"
echo "[4/4] Reloading Caddy..."
if sudo systemctl reload caddy; then
echo "✓ Caddy reloaded successfully"
else
echo "✗ Reload failed, rolling back..."
cp "$BACKUP" "$CONFIG_FILE"
sudo systemctl reload caddy
echo "✓ Rolled back to previous configuration"
exit 1
fi
# Opsional: health check setelah deploy
sleep 3
HTTP_STATUS=$(curl -sf -o /dev/null -w "%{http_code}" https://example.com/ 2>/dev/null)
if [ "$HTTP_STATUS" = "200" ]; then
echo "✓ Health check passed ($HTTP_STATUS)"
echo "✓ Deployment successful!"
else
echo "✗ Health check failed ($HTTP_STATUS), rolling back..."
cp "$BACKUP" "$CONFIG_FILE"
sudo systemctl reload caddy
exit 1
fi
Validasi di Git Hooks #
Cegah commit atau push konfigurasi yang tidak valid:
# .git/hooks/pre-commit (atau pre-push)
#!/bin/bash
# Cek apakah ada Caddyfile yang dimodifikasi
CADDYFILES=$(git diff --cached --name-only | grep -E "Caddyfile|\.caddyfile$")
if [ -n "$CADDYFILES" ]; then
echo "Validating Caddyfile changes..."
for file in $CADDYFILES; do
echo " Checking: $file"
if ! caddy validate --config "$file" 2>&1; then
echo "✗ Caddyfile validation failed: $file"
echo " Please fix the configuration before committing."
exit 1
fi
done
echo "✓ All Caddyfiles are valid"
fi
exit 0
# Install hook
chmod +x .git/hooks/pre-commit
Validasi dalam GitHub Actions CI #
# .github/workflows/validate-caddy.yml
name: Validate Caddy Config
on:
pull_request:
paths:
- 'caddy/**'
- '**/Caddyfile'
- '**/*.caddyfile'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Caddy
run: |
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
- name: Validate all Caddyfiles
run: |
EXIT_CODE=0
find . -name "Caddyfile" -o -name "*.caddyfile" | while read -r file; do
echo "Validating: $file"
if ! caddy validate --config "$file" 2>&1; then
echo "FAILED: $file"
EXIT_CODE=1
else
echo "PASSED: $file"
fi
done
exit $EXIT_CODE
- name: Comment PR with validation result
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '❌ **Caddyfile validation failed!** Please check the workflow logs for details.'
})
Validasi Konfigurasi dengan Substitusi Variable #
Ketika Caddyfile menggunakan environment variables, validasi perlu environment yang sesuai:
# Set environment variables yang diperlukan untuk validasi
export CF_API_TOKEN="test-token-for-validation"
export DB_HOST="localhost"
export ADMIN_PASSWORD_HASH='$2a$14$...'
# Validasi dengan environment variables tersedia
caddy validate --config /etc/caddy/Caddyfile
# Atau di CI/CD — set sebagai secrets GitHub Actions
# env:
# CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
Membandingkan Konfigurasi Lama dan Baru #
# Visualisasikan perbedaan konfigurasi
diff_configs() {
local old_config="$1"
local new_config="$2"
# Konversi keduanya ke JSON yang normalized
OLD_JSON=$(caddy adapt --config "$old_config" | jq -S .)
NEW_JSON=$(caddy adapt --config "$new_config" | jq -S .)
echo "$OLD_JSON" > /tmp/caddy-old.json
echo "$NEW_JSON" > /tmp/caddy-new.json
echo "=== Configuration Diff ==="
diff --color=always /tmp/caddy-old.json /tmp/caddy-new.json || true
}
# Gunakan
diff_configs /etc/caddy/Caddyfile.bak /etc/caddy/Caddyfile.new
Ringkasan #
caddy validatemengeksekusi provision dan validate secara dry-run — ini lebih dari sekedar syntax check, modul benar-benar diinisialisasi secara parsial.- Integrasikan
caddy validatedi pre-commit hook agar konfigurasi yang invalid tidak pernah masuk ke repository.- Di CI/CD pipeline, jalankan validasi sebagai langkah mandatory sebelum deployment — buat pipeline gagal jika validasi gagal.
- Gunakan exit code (
$?) daricaddy validatedalam scripting:0= valid,1= invalid.- Untuk Caddyfile yang menggunakan environment variables, pastikan env vars tersedia saat menjalankan validasi, atau gunakan nilai placeholder untuk testing.
caddy adapt+jq -Smenghasilkan JSON yang di-sort — berguna untukdiffyang bersih antara konfigurasi lama dan baru.
← Sebelumnya: Debug Konfigurasi Berikutnya: Tools Diagnostik →
Validasi Perubahan Incremental #
Saat melakukan perubahan besar, validasi secara incremental:
# Buat copy konfigurasi untuk iterasi
cp /etc/caddy/Caddyfile /tmp/caddy-work.caddyfile
# Edit dan validasi setiap perubahan
vim /tmp/caddy-work.caddyfile
caddy validate --config /tmp/caddy-work.caddyfile
# Ketika sudah valid dan siap deploy
cp /tmp/caddy-work.caddyfile /etc/caddy/Caddyfile
sudo systemctl reload caddy
Otomatisasi Validasi dengan Makefile #
# Makefile untuk workflow Caddy
.PHONY: validate deploy rollback
CADDYFILE = /etc/caddy/Caddyfile
BACKUP_DIR = /backup/caddy
validate:
@echo "Validating Caddyfile..."
@caddy validate --config $(CADDYFILE) && echo "✓ Valid"
deploy: validate
@echo "Deploying configuration..."
@cp $(CADDYFILE) $(BACKUP_DIR)/Caddyfile.$(shell date +%Y%m%d_%H%M%S)
@sudo systemctl reload caddy && echo "✓ Deployed"
rollback:
@echo "Rolling back to latest backup..."
@latest=$$(ls -t $(BACKUP_DIR)/Caddyfile.* | head -1); \
cp $$latest $(CADDYFILE) && \
sudo systemctl reload caddy && \
echo "✓ Rolled back to $$latest"
status:
@systemctl status caddy --no-pager
@echo ""
@curl -s http://localhost:2019/reverse_proxy/upstreams/ | \
jq -r '.[] | "\(.address): \(if .healthy then "UP" else "DOWN" end)"'
# Gunakan
make validate # Hanya validasi
make deploy # Validasi + deploy
make rollback # Rollback ke sebelumnya
make status # Lihat status