← Kembali ke Blog

HTTPS Tanpa Urusan Sertifikat: Caddy buat Situs Statis dan Reverse Proxy

Kamu deploy aplikasi ke server beneran, terus browser tetep nulis "not secure". Jadi kamu install certbot, bikin sertifikat, colokin ke config nginx, pasang cron job buat renew, dan di suatu titik lupa redirect HTTP ke HTTPS. Hasilnya semua visitor masuk redirect loop. Ngurusin sertifikat itu bagian paling membosankan dari maintain server, dan masalahnya selalu balik ke kamu.

Caddy adalah web server yang bikin kerjaan kategori ini ilang sama sekali. Arahkan ke satu domain, dia urus sendiri: ambil sertifikat TLS, pasang, renew. Gak ada certbot, gak ada cron, gak ada aturan redirect. Dia juga bisa serve file statis dan reverse proxy ke aplikasi kamu, semua dari satu file config kecil bernama Caddyfile.

Walkthrough ini ngeliput lima hal yang bakal beneran kamu lakuin: install Caddy, host situs statis dengan HTTPS otomatis, reverse proxy ke backend, load balance dua backend dengan health check, dan lindungi satu path dengan Basic Auth. Semua config di bawah udah dites pakai Caddy v2.11.4, release stabil terbaru per Juni 2026.

Prasyarat

  • Server Linux. Ubuntu atau Debian cocok buat langkah install di sini
  • Satu domain dengan record A atau AAAA yang ngarah ke IP publik server
  • Port 80 dan 443 bisa diakses dari internet. Caddy butuh ini karena otoritas sertifikat menghubungi server kamu lewat port 80 buat buktiin kamu pemilik domain
  • Nyaman pakai terminal. Itu aja syaratnya

Langkah 1: Install Caddy

Caddy punya package resmi untuk Debian dan Ubuntu. Tambah repository-nya, terus install:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
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 chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Baris-baris itu diambil langsung dari halaman install resmi. Package-nya sekalian ngasih systemd service, jadi Caddy jalan dan restart kayak service normal.

Cek versi yang keinstall:

caddy version

Line stable sekarang di v2, dan release terbaru pas artikel ini ditulis adalah v2.11.4.

Langkah 2: Tulis Caddyfile pertama kamu

Caddy baca file bernama Caddyfile, dan caddy run nyari file itu di direktori aktif. Di package Debian, service-nya jalan dengan config di /etc/caddy/Caddyfile.

Formatnya: alamat situs diikuti directive yang di-indent. Contoh situs statis:

example.com {
    root * /var/www/example
    file_server
}

Dua baris config. root nentuin folder-nya, file_server serve file-nya lewat HTTP. Karena nama situsnya domain publik beneran, Caddy sekalian nyalain automatic HTTPS buat situs itu dan redirect traffic HTTP ke HTTPS.

Gimana kalau mau ganti config di server yang lagi jalan? Pakai:

sudo systemctl reload caddy

Pakai reload, jangan restart. Docs-nya tegas soal ini: stop server cuma buat ganti config di production itu bikin downtime. caddy reload pindah config tanpa mutus koneksi.

Langkah 3: Automatic HTTPS, dan dua hal yang dia butuh dari kamu

Kamu gak bikin sertifikat di mana-mana, tapi situs udah ke-serve lewat HTTPS dengan sertifikat valid. Itu kerjaan automatic HTTPS.

Ini yang terjadi. Caddy ngobrol sama otoritas sertifikat ACME publik, default-nya Let's Encrypt atau ZeroSSL, dan minta sertifikat buat domain kamu. Otoritasnya ngasih ACME challenge buat mastiin kamu beneran kontrol domain itu, dan Caddy jawab otomatis. Sertifikat Let's Encrypt berlaku 90 hari, dan Caddy renew semua sertifikat yang dia kelola sebelum kadaluarsa, di background, selamanya. Kamu gak pernah pegang urusan ini.

Dua syarat setup yang nentuin berhasil gaknya:

  1. Record DNS domain kamu harus ngarah ke server ini. Caddy melakukan authoritative DNS lookup buat hostname kamu sebagai bagian dari HTTP challenge.
  2. Port 80 harus kebuka. Otoritas nyamperin kamu lewat port 80 buat ngasih challenge, dan Caddy juga pakai port 80 buat redirect HTTP ke HTTPS.

Kalau record DNS-nya salah, provisioning sertifikat gagal. Caddy tetep nyoba di background, tapi urusin DNS duluan biar gak bingung sendiri.

Mau testing di server yang belum live? Docs nyaranin ganti ACME endpoint ke staging server Let's Encrypt. Endpoint produksi punya rate limit, dan kena rate limit pas eksperimen bisa ngeblok penerbitan sertifikat sampai seminggu.

Langkah 4: Reverse proxy ke aplikasi kamu

App kamu service Node, Go, atau Python yang dengerin di port tertentu, misalnya localhost:8080. Buka aksesnya dengan:

api.example.com {
    reverse_proxy localhost:8080
}

Request ke api.example.com diterusin ke app di port 8080. WebSocket jalan tanpa config tambahan, Caddy yang handle upgrade-nya. Satu baris yang sama bisa proxy app FastAPI di port 8000, server Node di port 3000, atau Spring Boot di 8080. Bahasa pemrogramannya gak pernah jadi masalah.

Langkah 5: Load balance dua backend, lengkap dengan health check

reverse_proxy nerima daftar upstream, dan Caddy load balance antar mereka secara default:

app.example.com {
    reverse_proxy 10.0.0.11:8080 10.0.0.12:8080
}

Traffic nyebar ke dua server. Tapi sendirian, config ini tetep ngirim request ke backend yang lagi mati. Active health check nyelesaiin itu:

app.example.com {
    reverse_proxy 10.0.0.11:8080 10.0.0.12:8080 {
        health_uri /health
        health_interval 10s
        health_timeout 5s
    }
}

Caddy nembak GET /health ke tiap backend tiap 10 detik. Backend yang gak jawab dalam 5 detik ditandain down dan berhenti nerima traffic sampai dia jawab lagi. Default-nya interval 30 detik dan timeout 5 detik, jadi contoh di atas ngecilin dua-duanya. Kalau app kamu belum punya endpoint /health, tambahin. Itu hook yang diharapin semua load balancer.

Pola ini pernah saya tes lokal pakai dua backend dan interval 2 detik. Pas backend kedua saya matiin, health checker-nya nyatet probe yang gagal tiap 2 detik dan Caddy ngirim semua request ke backend yang masih hidup. Gak ada satu request pun yang nyampe ke server mati.

Langkah 6: Lindungi satu path dengan Basic Auth

Caddy punya Basic Auth bawaan, dan dia gak nerima password plaintext, jadi hash dulu:

caddy hash-password

Command itu minta password lalu ngeprint hash bcrypt. Bisa juga dikasih langsung: caddy hash-password --plaintext 's3cret-pass'. Tempel hash-nya ke Caddyfile bareng username dan matcher yang nargetin path yang mau dilindungin:

example.com {
    root * /var/www/example
    file_server

    @private path /admin/*
    basic_auth @private {
        arya $2a$14$ilwb1R4PDutllnO73dRiAORmyjHWwO54hpPjHnKqm/OyyScOoUs/S
    }
}

Visitor yang buka /admin/ dikasih popup password di browser. Kredensial salah dapet HTTP 401 Unauthorized. bcrypt itu algoritma hash default, dan argon2id tersedia kalau mau yang lebih kuat. Jangan taruh password plaintext di file ini, Caddy bakal nolak config-nya.

Langkah 7: Biarin Caddy tetep jalan dan cek kerjaan kamu

Package resmi ngikutin unit systemd. Enable biar Caddy nyala pas boot:

sudo systemctl enable --now caddy
systemctl status caddy

Log masuk ke journal:

journalctl -u caddy -f

Sebelum apply perubahan yang belum yakin, validasi config dulu tanpa nyentuh server yang jalan:

caddy validate --config /etc/caddy/Caddyfile

Atau liat persis apa yang Caddy ubah dari Caddyfile kamu:

caddy adapt --config /etc/caddy/Caddyfile

Itu ngeprint config JSON yang beneran dijalanin Caddy, bagus buat belajar arti singkatan Caddyfile.

Kapan pakai Caddy vs alternatifnya

nginx: pilih ini kalau kamu udah tinggal di ecosystem-nya, butuh routing request yang sangat custom, URL rewriting, atau module yang gak disediain Caddy. nginx punya puluhan tahun ekstensi dan opsi tuning. Caddy menang telak di urusan TLS dan config yang ringkas, tapi nginx menang kalau butuh kontrol yang sangat detail.

Traefik: sama-sama otomatis urus sertifikat, tapi Traefik dibangun di sekitar service discovery dinamis. Dia baca label dari container di Docker dan Kubernetes, terus reconfigure sendiri pas service muncul dan ilang. Kalau workload kamu containerized dan sering berubah, Traefik pas. Kalau kamu cuma pegang beberapa server dengan service yang sedikit, satu Caddyfile lebih ringan daripada seluruh model Traefik.

Kelemahan jujur Caddy: usianya lebih muda, jadi plugin ecosystem-nya lebih tipis, dan model config-nya, alamat situs lalu directive, kurang ekspresif buat penanganan request yang nggak biasa. Buat situs statis, reverse proxy, dan HTTPS, effort-nya jauh lebih kecil.

Kesimpulan

Caddy cara tercepat buat naruh sesuatu di internet dengan HTTPS yang beneran tetep valid. Dua baris buat situs statis. Satu baris buat reverse proxy. Nol kerja manual soal sertifikat, karena renewal berhenti jadi masalah kamu sejak pertama kali install.

Mulai dari satu domain yang diarahin ke server kamu, biarin TLS jalan sendiri. Terus tambahin reverse proxy ke apa pun yang jalan lokal, dan lupain tarian sertifikat selamanya.

Referensi

Butuh Bantuan Implementasi?

Saya membantu tim mendesain dan membangun infrastruktur cloud scalable, pipeline DevOps, dan sistem production-grade.

Konsultasi Gratis