Pengalaman Menggunakan Caddy + Cloudflare untuk Homelab: Dari Chaos ke Zen

Intro: Dari Disaster ke Salvation

Sebagai SRE engineer, saya tau betul gimana ribetnya manage reverse proxy dan SSL certificates di production. Tapi ternyata, masalah yang sama juga muncul di homelab pribadi.

Desember 2024 kemarin, saya sempat mengalami disaster yang cukup traumatis. Waktu itu setup homelab saya menggunakan Nginx Proxy Manager + Cloudflare di Raspberry Pi. Semuanya berjalan normal sampai suatu hari Pi saya tiba-tiba mati (belum punya UPS waktu itu).

Ketika Pi hidup lagi, database yang dipakai Nginx Proxy Manager ternyata corrupt. Semua konfigurasi proxy, SSL certificates, access rules - semuanya hilang. Dan yang lebih parah, saya belum punya backup yang proper.

Frustasi banget, saya searching alternative dan ketemu Caddy. Ternyata, ini adalah blessing in disguise. Sejak beralih ke Caddy + Cloudflare, setup homelab saya jauh lebih stable dan mudah di-maintain.

Kenapa Pilih Caddy setelah NPM Disaster?

Caddy: File-based Configuration (No Database!)

1
2
3
4
5
- Konfigurasi disimpan dalam Caddyfile (plain text)
- Tidak ada database yang bisa corrupt
- Auto SSL dari Let's Encrypt
- Zero-downtime reloads
- Built-in load balancing

Cloudflare: CDN + Security Layer

1
2
3
4
- DDoS protection gratis
- Global CDN network
- Web Application Firewall
- Analytics yang detail

Poin utama yang membuat saya switch: no database dependency. Semua konfigurasi Caddy disimpan dalam file teks biasa. Kalau Pi saya mati lagi, tinggal copy Caddyfile dan jalankan ulang. Simple!

Arsitektur Hybrid yang Saya Gunakan

Setup saya agak unik karena menggunakan hybrid approach, terutama karena ISP saya tidak memberikan IP public (menggunakan CGNAT). Ini sebenarnya jadi blessing in disguise karena memaksa saya untuk mencari solusi yang lebih aman.

Public Services (via Cloudflare Zero Trust)

1
Internet → Cloudflare Zero Trust → abdullahainun.site

Local-only Services (via Caddy DNS Challenge)

1
2
3
Local Network → Caddy → linkding.abdullahainun.site
                     → books.abdullahainun.site
                     → other internal services

Karena tidak punya IP public, saya tidak bisa expose port apapun ke internet secara langsung. Semua subdomain seperti linkding.abdullahainun.site, books.abdullahainun.site, dan photos.abdullahainun.site hanya bisa diakses dari jaringan local, tapi tetap dapat SSL certificate yang valid melalui DNS challenge ke Cloudflare

Dengan setup ini, saya mendapat keuntungan maksimal:

  • SSL valid untuk semua services - Berkat DNS challenge, semua subdomain punya certificate yang auto-renew tanpa perlu expose ke internet
  • Keamanan maksimal - Services internal tetap aman di local network, tidak bisa diakses dari luar
  • Fleksibilitas akses - Kalau suatu saat butuh akses remote, tinggal enable Zero Trust untuk service tertentu tanpa merubah konfigurasi Caddy

Setup Awal: Domain & Cloudflare

Step 1: Domain Management

Saya pindahkan domain ke Cloudflare (free tier sudah cukup):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# DNS records yang saya set
Type: A
Name: @
Content: [public-IP]
Proxy: Enabled

Type: CNAME  
Name: *
Content: yourdomain.com
Proxy: Enabled

Step 2: API Token

Buat API token di Cloudflare dengan permissions:

  • Zone:Zone:Read
  • Zone:DNS:Edit
  • Zone:Zone Settings:Read

Simpan token ini, kita butuh untuk DNS challenge nanti.

Instalasi Caddy

Docker Compose Setup

Saya prefer Docker karena lebih mudah manage:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
version: '3.8'

services:
  caddy:
    image: ghcr.io/caddybuilds/caddy-cloudflare:latest
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./html:/var/www/html
      - caddy_data:/data
      - caddy_config:/config
    env_file:
      - .env

volumes:
  caddy_data:
    external: true
  caddy_config:

networks:
  default:
    ipam:
      config:

Environment File

1
2
3
# .env
CF_API_TOKEN=your_cloudflare_api_token_here
DOMAIN=yourdomain.com

Caddyfile: Konfigurasi yang Saya Gunakan

Global Settings

1
2
3
4
5
6
7
8
9
{
    email [email protected]
    acme_dns cloudflare {$CLOUDFLARE_API_TOKEN}
}

:80 {
    root * /var/www/html
    file_server
}

Local Services Configuration

Ini contoh service-service internal yang saya jalankan (hanya bisa diakses dari local network):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Linkding - Bookmark Manager
linkding.abdullahainun.site {
    reverse_proxy linkding:9090
}

# Calibre Web - Book Management
books.abdullahainun.site {
    reverse_proxy calibre-web:8083
}

# Immich - Photo Management (Self-hosted Google Photos alternative)
photos.abdullahainun.site {
    reverse_proxy immich:3001
}

Keunggulan Setup Hybrid Ini

1. Cocok untuk CGNAT/Tanpa IP Public

Banyak ISP rumahan di Indonesia menggunakan CGNAT (Carrier-Grade NAT), jadi tidak bisa port forwarding. Setup ini bisa solve masalah tersebut dengan baik.

2. Security Through Obscurity

Services internal seperti linkding.abdullahainun.site, books.abdullahainun.site, dan photos.abdullahainun.site tidak exposed ke internet sama sekali. Hanya bisa diakses dari local network, tapi tetap punya SSL yang valid.

3. Zero Port Forwarding

Tidak perlu buka port 80/443 di router. Semua tetap aman di belakang firewall.

4. Valid SSL Everywhere

Meskipun local-only, semua subdomain punya SSL certificate yang valid berkat DNS challenge. Browser tidak complain dengan warning certificate, experience sama seperti accessing public sites.

5. Cloudflare Zero Trust untuk Public Access

Kalau butuh akses dari luar, bisa setup Cloudflare Zero Trust untuk specific services tanpa expose homelab directly.

6. Best of Both Worlds

  • Internal services: Fast access, no latency dari CDN
  • Public services: Protected oleh Cloudflare security features

Belajar dari NPM Disaster: Backup Strategy

Setelah kehilangan semua konfigurasi NPM, saya jadi lebih aware soal backup. Dengan Caddy, backup jauh lebih simple karena cuma perlu backup beberapa file text.

Yang saya lakukan sekarang:

Git Repository untuk Configuration

Semua konfigurasi Caddy saya simpan di GitHub repository. Ini include:

  • Caddyfile - Main configuration
  • docker-compose.yml - Container orchestration
  • .env.example - Environment template (tanpa sensitive data)
  • README.md - Documentation setup

Keuntungannya:

  • Version control - Bisa track perubahan dan rollback kalau ada masalah
  • Remote backup - Konfigurasi tersimpan di cloud secara otomatis
  • Easy restore - Tinggal git clone kalau Pi mati lagi
  • Documentation - Semua setup terdokumentasi dengan baik

Jauh lebih reliable dibanding backup database NPM yang bisa corrupt.

Lessons Learned & Recommendations

Yang Berhasil

  1. Simplicity wins - Caddyfile jauh lebih readable dibanding Nginx config
  2. Automation is key - Auto SSL renewal mengurangi stress significantly
  3. Security by default - Cloudflare + proper headers memberikan protection yang bagus

Yang Perlu Diperhatikan

  1. DNS Records Configuration - Pastikan wildcard record pointing ke local IP dan tidak di-proxy
  2. Cloudflare API Token - Harus punya permission untuk DNS management
  3. Local DNS Resolution - Router atau DNS local harus bisa resolve subdomain ke local IP
  4. Certificate Storage - Pastikan volume persistence untuk avoid re-issuing certificates
  5. CGNAT Limitation - Setup ini cocok untuk yang tidak punya IP public, tapi kalau punya IP public bisa menggunakan hybrid approach
  6. Zero Trust Setup - Untuk remote access, perlu setup Cloudflare tunnel yang separate dari Caddy

Kesimpulan

Setelah beberapa bulan menggunakan setup hybrid ini (sejak Desember 2024), saya bisa bilang ini adalah salah satu keputusan terbaik setelah disaster NPM. Kombinasi Caddy + Cloudflare DNS Challenge + Zero Trust memberikan:

  • Security: Tidak ada port yang exposed, tapi tetap bisa akses dari luar kalau perlu
  • SSL Everywhere: Valid certificates untuk semua subdomain, bahkan yang local-only
  • Simplicity: Tidak perlu manage self-signed certificates atau port forwarding
  • Flexibility: Bisa pilih mana yang mau exposed via Zero Trust, mana yang tetap internal
  • Disaster Recovery: File-based configuration, mudah backup dan restore

Setup ini cocok untuk SRE yang mau belajar dan experimenting di homelab tanpa takut soal security exposure. Dan bonus: tidak ada database yang bisa corrupt lagi!


Note:

  • Setup hybrid ini sudah running stable di homelab saya sejak Desember 2024, serving 10+ internal services dengan SSL yang valid dan 1 public service via Zero Trust. Perfect balance antara security dan convenience!
  • Artikel ini ditulis dengan bantuan AI untuk mempercepat proses penulisan dan strukturisasi konten, namun semua pengalaman dan konfigurasi teknis adalah hasil implementasi nyata di homelab pribadi.