Caddy Validate #

Perintah caddy validate adalah salah satu utilitas paling penting bagi operator server Caddy. Perintah ini melakukan validasi menyeluruh pada berkas konfigurasi Caddy tanpa benar-benar menjalankan server web atau menghentikan lalu lintas yang sedang aktif. Dalam alur kerja (workflow) deployment modern yang aman, memvalidasi konfigurasi sebelum melakukan pemuatan ulang (reload) adalah langkah wajib guna mencegah padamnya layanan (downtime) akibat kesalahan ketik atau logika konfigurasi.

Alur Kerja Internal Validasi Dry-Run Caddy #

Berbeda dengan server web tradisional yang hanya memeriksa aturan penulisan kata kunci (syntax check), Caddy melakukan validasi yang jauh lebih mendalam. Saat kita menjalankan caddy validate, Caddy melakukan simulasi penuh pembuatan server (dry-run provisioning).

Berikut adalah alur tahapan evaluasi konfigurasi yang dilakukan Caddy di latar belakang:

flowchart TD
    Input["Mulai: caddy validate --config Caddyfile"] --> Parse["Parsing Token Caddyfile"]
    Parse --> ParseCheck{"Parsing Sukses?"}
    
    ParseCheck -- Tidak --> ParseError["Syntax Error (Exit Code 1)"]
    ParseCheck -- Ya --> Adapt["Adaptasi Caddyfile ke JSON Internal"]
    
    Adapt --> Provision["Inisialisasi & Provisioning Modul (Dry-Run)"]
    Provision --> ProvCheck{"Provisioning Sukses?"}
    
    ProvCheck -- Tidak --> ProvError["Semantic / Module Error (Exit Code 1)"]
    ProvCheck -- Ya --> Validate["Validasi Logika Modul (Validate)"]
    
    Validate --> ValCheck{"Validasi Sukses?"}
    
    ValCheck -- Tidak --> ValError["Logic / Configuration Error (Exit Code 1)"]
    ValCheck -- Ya --> Success["Valid Configuration (Exit Code 0)"]
    
    style Input stroke:#0288d1,stroke-width:2px
    style Success stroke:#2e7d32,stroke-width:2px
    style ParseError stroke:#c62828,stroke-width:2px
    style ProvError stroke:#c62828,stroke-width:2px
    style ValError stroke:#c62828,stroke-width:2px

Selama fase provisioning dan validation kering ini, Caddy benar-benar membuat objek di memori, memeriksa keberadaan modul plugin yang terdaftar di biner, memvalidasi parameter sertifikat, serta memastikan nomor port yang diminta masuk akal. Caddy hanya melepaskan proses tepat sebelum soket TCP diduduki (port binding).


Penggunaan Dasar caddy validate #

Kita dapat memvalidasi konfigurasi Caddy dari berbagai sumber—baik berupa berkas Caddyfile lokal, berkas berformat JSON, maupun data konfigurasi yang dialirkan langsung dari pipa perintah Linux (standard input).

# 1. Validasi berkas Caddyfile bawaan di lokasi standar
caddy validate --config /etc/caddy/Caddyfile

# 2. Validasi berkas konfigurasi dengan nama kustom
caddy validate --config /home/user/project/Caddyfile

# 3. Validasi konfigurasi berformat JSON asli
caddy validate --config /etc/caddy/config.json --adapter json

# 4. Validasi data konfigurasi yang dialirkan dari standard input (stdin)
# Sangat berguna untuk pengujian dinamis di skrip otomatisasi
cat /etc/caddy/Caddyfile | caddy validate --config /dev/stdin

# 5. Validasi Caddyfile dan langsung cetak representasi JSON jika valid
caddy validate --config /etc/caddy/Caddyfile && \
    caddy adapt --config /etc/caddy/Caddyfile | jq .

Menganalisis dan Menginterpretasikan Output Validasi #

Memahami jenis kesalahan dari output caddy validate membantu kita menemukan solusi dengan cepat. Berikut adalah analisis tipe-tipe kesalahan yang sering ditangkap oleh validator Caddy:

1. Kesalahan Sintaksis (Syntax Error) #

Validator langsung berhenti di fase parse token awal. Biasanya karena kesalahan pengetikan kata kunci (directive) atau kurung kurawal tidak berpasangan.

$ caddy validate --config Caddyfile
parsing Caddyfile tokens: Caddyfile:12 - Error during parsing: unrecognized directive: rverse_proxy
  • Solusi: Periksa baris 12 pada berkas Caddyfile Anda dan ganti rverse_proxy dengan reverse_proxy.

2. Kesalahan Modul Tidak Terdaftar (Missing Plugin Module) #

Validator lolos fase parse, namun gagal saat mencoba merakit modul internal. Ini terjadi jika kita menulis konfigurasi untuk plugin (seperti dns.providers.cloudflare atau rate_limit) namun menggunakan binary Caddy standar yang belum dikompilasi dengan plugin tersebut.

$ caddy validate --config Caddyfile
loading initial config: loading new config: http app module: provisioning http handlers: handler module "rate_limit" not registered
  • Solusi: Kompilasi ulang binary Caddy Anda menggunakan xcaddy dengan menyertakan modul yang hilang.

3. Kesalahan Semantik Nilai (Invalid Parameter Values) #

Kesalahan ini ditangkap di fase akhir validator. Kode sintaksis Anda benar, namun nilai parameter yang dimasukkan tidak masuk akal (misalnya format URL salah atau port bernilai negatif).

$ caddy validate --config Caddyfile
loading initial config: loading new config: tls app: invalid ACME CA URL: "https://invalid-ca-url"
  • Solusi: Perbaiki URL otoritas sertifikat (CA URL) pada bagian opsi global Caddyfile Anda.

Integrasi Validasi di Pre-Deploy Script #

Untuk memastikan kenyamanan kerja tim operasi, kita harus membungkus proses deployment Caddy ke dalam skrip otomatisasi defensif. Skrip ini akan melakukan pencadangan konfigurasi, memvalidasi berkas baru, lalu melakukan pemuatan ulang (graceful reload) dengan mekanisme pemulihan otomatis (automatic rollback) jika terjadi kegagalan:

#!/bin/bash
# safe-deploy.sh — Deployment Caddy yang aman dengan validasi dan rollback
set -euo pipefail

CONFIG_FILE="/etc/caddy/Caddyfile"
NEW_CONFIG="${1:-}"

# Pastikan argumen input berkas diberikan
if [ -z "$NEW_CONFIG" ]; then
    echo "Penggunaan: $0 <path-to-new-caddyfile>"
    exit 1
fi

echo "[1/4] Memvalidasi konfigurasi baru..."
if ! caddy validate --config "$NEW_CONFIG" 2>&1; then
    echo "✗ Validasi konfigurasi GAGAL!"
    echo "   Deployment dibatalkan. Konfigurasi aktif tidak diubah."
    exit 1
fi
echo "✓ Konfigurasi dinyatakan VALID."

echo "[2/4] Membuat salinan cadangan konfigurasi saat ini..."
BACKUP_FILE="/etc/caddy/Caddyfile.bak.$(date +%Y%m%d_%H%M%S)"
cp "$CONFIG_FILE" "$BACKUP_FILE"
echo "✓ Cadangan disimpan di: $BACKUP_FILE"

echo "[3/4] Mengaplikasikan berkas konfigurasi baru..."
cp "$NEW_CONFIG" "$CONFIG_FILE"

echo "[4/4] Memuat ulang konfigurasi Caddy (Reload)..."
if sudo systemctl reload caddy; then
    echo "✓ Caddy berhasil dimuat ulang dengan konfigurasi baru!"
else
    echo "✗ Gagal memuat ulang Caddy! Melakukan pemulihan (Rollback)..."
    cp "$BACKUP_FILE" "$CONFIG_FILE"
    sudo systemctl reload caddy
    echo "✓ Pemulihan berhasil. Caddy berjalan dengan konfigurasi lama."
    exit 1
fi

# Langkah Opsional: Pengujian kesehatan situs pasca-deployment
echo "[+] Menunggu inisialisasi jaringan..."
sleep 2
HTTP_STATUS=$(curl -sf -o /dev/null -w "%{http_code}" https://localhost/health 2>/dev/null || echo "000")

if [ "$HTTP_STATUS" = "200" ]; then
    echo "✓ Pengujian kesehatan berhasil (HTTP $HTTP_STATUS)."
    echo "✓ Deployment selesai dengan sukses!"
else
    echo "✗ Uji kesehatan gagal (HTTP $HTTP_STATUS)! Melakukan rollback..."
    cp "$BACKUP_FILE" "$CONFIG_FILE"
    sudo systemctl reload caddy
    echo "✓ Pemulihan ke konfigurasi lama berhasil diaplikasikan."
    exit 1
fi

Validasi Otomatis via Git Hooks (Pre-Commit) #

Kita bisa mencegah konfigurasi yang rusak masuk ke dalam repositori kode git dengan memasang pre-commit hook. Langkah ini memastikan bahwa setiap kali developer menjalankan git commit pada file Caddyfile, validator akan berjalan secara otomatis di lokal mereka:

# Buat file hook di repositori lokal Anda: .git/hooks/pre-commit
#!/bin/bash
set -u

# Lacak berkas Caddyfile yang masuk dalam staging git (staged changes)
CADDYFILES=$(git diff --cached --name-only | grep -E "Caddyfile|\.caddyfile$")

if [ -n "$CADDYFILES" ]; then
    echo "=== Menjalankan Validasi Caddyfile ==="
    
    for file in $CADDYFILES; do
        # Lewati validasi jika berkas dihapus
        if [ ! -f "$file" ]; then
            continue
        fi
        
        echo "Memeriksa: $file"
        if ! caddy validate --config "$file" 2>&1; then
            echo "✗ Validasi GAGAL pada berkas: $file"
            echo "   Silakan perbaiki kesalahan sebelum melakukan commit."
            exit 1
        fi
    done
    
    echo "✓ Semua berkas Caddyfile valid. Melanjutkan commit..."
fi

exit 0

Pastikan skrip hook tersebut memiliki izin eksekusi:

chmod +x .git/hooks/pre-commit

Validasi Konfigurasi dalam CI/CD Pipeline (GitHub Actions) #

Di lingkungan korporat, seluruh berkas konfigurasi dikelola menggunakan pendekatan GitOps. Kita bisa membuat alur kerja (pipeline) GitHub Actions yang memvalidasi berkas konfigurasi Caddy secara otomatis setiap kali ada permintaan penggabungan kode (Pull Request):

# .github/workflows/validate-caddy.yml
name: Caddyfile Linter & Validator

on:
  pull_request:
    paths:
      - '**/Caddyfile'
      - '**/*.caddyfile'

jobs:
  validate:
    name: Validate Configuration
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4
        
      - name: Install Caddy
        run: |
          sudo apt-get 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-get update
          sudo apt-get install -y caddy
                    
      - name: Locate and Validate Caddyfiles
        run: |
          EXIT_STATUS=0
          # Temukan semua berkas dengan nama Caddyfile atau berakhiran .caddyfile
          find . -type f \( -name "Caddyfile" -o -name "*.caddyfile" \) | while read -r file; do
              echo "Validating: $file"
              if ! caddy validate --config "$file" 2>&1; then
                  echo "::error file=$file::Validation failed for $file"
                  EXIT_STATUS=1
              else
                  echo "✓ $file is valid"
              fi
          done
          exit $EXIT_STATUS          

      - name: Notify on Failure
        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: '🚨 **Peringatan Integrasi:** Validasi Caddyfile gagal pada Pull Request ini. Silakan periksa log aksi GitHub untuk detail kesalahan.'
            })            

Validasi Konfigurasi dengan Substitusi Environment Variable #

Jika berkas Caddyfile kita menggunakan variabel lingkungan (environment variables) seperti {$DB_PORT} atau {$CF_API_TOKEN}, menjalankan caddy validate secara mentah akan menghasilkan kesalahan karena variabel tersebut bernilai kosong di lingkungan shell.

Kita harus menyediakan nilai uji coba (mock value) saat menjalankan validator:

# Jalankan validasi dengan menyuntikkan variabel lingkungan tiruan di depannya
CF_API_TOKEN="mock-token-value" \
DB_PORT="3306" \
caddy validate --config /etc/caddy/Caddyfile

Dengan cara ini, parser Caddy dapat menyelesaikan proses interpolasi variabel tanpa mendeteksi adanya error missing variables.


Membandingkan Perubahan Konfigurasi Secara Visual #

Sebelum meluncurkan konfigurasi baru, kita harus meneliti perbedaan (diff) antara versi yang aktif di memori dengan versi baru. Untuk menghindari perbedaan spasi dan formatting Caddyfile yang tidak relevan, kita mengonversi kedua file ke format JSON yang sudah diurutkan (sorted normalized JSON):

# Fungsi pembantu untuk membandingkan konfigurasi
diff_caddy_configs() {
    local old_config="$1"
    local new_config="$2"
    
    # Konversi dan urutkan objek JSON secara alfabetis (jq -S)
    caddy adapt --config "$old_config" | jq -S . > /tmp/caddy-old.json
    caddy adapt --config "$new_config" | jq -S . > /tmp/caddy-new.json
    
    echo "=== PERBEDAAN STRUKTUR JSON GATEWAY ==="
    diff --color=always -u /tmp/caddy-old.json /tmp/caddy-new.json || true
}

# Jalankan perbandingan
diff_caddy_configs /etc/caddy/Caddyfile.bak /etc/caddy/Caddyfile

Validasi Perubahan Secara Incremental #

Saat melakukan perubahan arsitektur Caddyfile yang besar, jangan mengedit file produksi secara langsung. Gunakan alur kerja inkremental berikut untuk menghindari kesalahan tidak terduga:

# 1. Buat salinan berkas Caddyfile ke direktori kerja sementara
cp /etc/caddy/Caddyfile /tmp/caddy-sandbox.caddyfile

# 2. Lakukan pengeditan konfigurasi pada berkas sandbox tersebut
nano /tmp/caddy-sandbox.caddyfile

# 3. Jalankan validasi secara berulang setiap kali selesai menambahkan satu fitur
caddy validate --config /tmp/caddy-sandbox.caddyfile

# 4. Setelah konfigurasi sandbox dinyatakan valid, salin kembali ke lokasi utama
sudo cp /tmp/caddy-sandbox.caddyfile /etc/caddy/Caddyfile
sudo systemctl reload caddy

Otomatisasi Alur Kerja dengan Makefile #

Untuk memudahkan tim pengembang dan tim operasi dalam menjalankan tugas-tugas administratif Caddy secara seragam, kita dapat menyusun berkas Makefile pada server:

# /etc/caddy/Makefile
.PHONY: validate deploy rollback status

CADDYFILE = /etc/caddy/Caddyfile
BACKUP_DIR = /var/backups/caddy

validate:
	@echo "[+] Memvalidasi konfigurasi Caddyfile..."
	@caddy validate --config $(CADDYFILE)

deploy: validate
	@echo "[+] Membuat folder cadangan..."
	@mkdir -p $(BACKUP_DIR)
	@echo "[+] Mencadangkan konfigurasi aktif..."
	@cp $(CADDYFILE) $(BACKUP_DIR)/Caddyfile.bak.$(shell date +%Y%m%d_%H%M%S)
	@echo "[+] Memuat ulang konfigurasi Caddy (Reload)..."
	@sudo systemctl reload caddy
	@echo "[✓] Deployment sukses!"

rollback:
	@echo "[+] Mencari salinan cadangan terakhir..."
	@latest_backup=$$(ls -t $(BACKUP_DIR)/Caddyfile.bak.* | head -n 1); \
	if [ -z "$$latest_backup" ]; then \
		echo "[-] Tidak ada file cadangan ditemukan!"; \
		exit 1; \
	fi; \
	echo "[+] Memulihkan ke berkas: $$latest_backup"; \
	cp $$latest_backup $(CADDYFILE) && \
	sudo systemctl reload caddy && \
	echo "[✓] Rollback berhasil diselesaikan."

status:
	@sudo systemctl status caddy --no-pager

Kita hanya perlu mengetikkan perintah sederhana berikut di terminal server:

  • make validate — Untuk memvalidasi konfigurasi.
  • make deploy — Untuk memvalidasi, mencadangkan, dan memuat ulang Caddy.
  • make rollback — Untuk memulihkan konfigurasi secara otomatis ke cadangan terakhir.

Ringkasan #

  • Dry-Run Simulation — Validator Caddy tidak hanya memeriksa penulisan teks sintaks, melainkan melakukan instansiasi objek dan inisialisasi dry-run modul secara utuh di memori.
  • Deteksi Cepat Plugin — Kegagalan inisialisasi modul (seperti handler not registered) saat validasi adalah indikator bahwa biner Caddy kita belum dipasangi plugin yang dibutuhkan.
  • Git Commit Safety — Pemasangan git pre-commit hook mencegah konfigurasi yang rusak dan tidak valid masuk ke dalam repositori kode git tim pengembang.
  • Integrasi CI/CD — Manfaatkan GitHub Actions untuk memvalidasi setiap berkas Caddyfile pada Pull Request secara otomatis guna mendukung alur kerja GitOps yang tangguh.
  • Penanganan Env Vars — Nilai tiruan (mock values) harus diekspor ke shell jika berkas Caddyfile kita menggunakan substitusi variabel lingkungan agar validator tidak error.
  • makefile Standardization — Penggunaan berkas Makefile di server membantu standarisasi operasi validate, deploy, dan rollback untuk seluruh staf operasional.

← Sebelumnya: Debug Konfigurasi   Berikutnya: Tools Diagnostik →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact