Transport #
Transport dalam konteks reverse proxy Caddy adalah lapisan yang menentukan bagaimana koneksi ke backend dibuat dan dikelola — bukan ke mana traffic dikirim (itu urusan upstream), tapi protokol apa yang digunakan, bagaimana TLS dikonfigurasi, berapa timeout-nya, dan bagaimana koneksi dikelola.
Memahami transport penting karena ini yang menentukan performa koneksi ke backend, keamanan koneksi (apakah mTLS diaktifkan), dan kompatibilitas dengan berbagai jenis backend (HTTP biasa, HTTPS, FastCGI, NTLM).
Jenis Transport yang Tersedia #
Transport Type Kegunaan
───────────────────────────────────────────────────────────────────
http Default — untuk backend HTTP/HTTPS biasa
fastcgi Untuk backend PHP-FPM via FastCGI protocol
Jika tidak dikonfigurasi, Caddy menggunakan transport http secara default.
HTTP Transport — Semua Opsi #
example.com {
reverse_proxy backend:3000 {
transport http {
# ═══ TLS ke Backend ═══════════════════════════════════════
# Aktifkan TLS untuk koneksi ke backend
# (diperlukan jika backend URL menggunakan https://)
tls
# Verifikasi sertifikat backend (default: verifikasi)
# JANGAN gunakan di production — hanya untuk development
tls_insecure_skip_verify
# Trusted CA untuk verifikasi sertifikat backend
# Gunakan jika backend punya sertifikat dari internal CA
tls_trusted_ca_certs /path/to/ca.pem
# Client certificate (untuk mutual TLS / mTLS)
tls_client_auth /path/to/client.pem /path/to/client-key.pem
# SNI yang dikirim ke backend saat TLS handshake
# Default: hostname dari upstream address
tls_server_name internal-backend.example.com
# Versi TLS minimum untuk koneksi ke backend
tls_min_version tls1.2
# ═══ Timeout ══════════════════════════════════════════════
# Waktu maksimal untuk membuat koneksi TCP + TLS ke backend
# Default: tidak terbatas (mengikuti timeout OS)
dial_timeout 5s
# Timeout untuk menerima header response dari backend
# Mulai dihitung setelah request dikirim ke backend
# Default: tidak terbatas
response_header_timeout 30s
# Timeout untuk menerima body response dari backend setelah header
# JANGAN set ini untuk streaming response atau download besar
# Default: tidak terbatas
# read_timeout 60s
# Waktu koneksi idle dipertahankan di pool
# Default: 90s (mengikuti net/http Go)
keep_alive 90s
# ═══ Connection Pool ═══════════════════════════════════════
# Jumlah maksimal koneksi idle per upstream
# Default: tidak terbatas
max_idle_conns_per_host 100
# Jumlah maksimal koneksi total (termasuk aktif + idle)
# Default: tidak terbatas
# max_conns_per_host 200
# ═══ Buffer Size ═══════════════════════════════════════════
# Ukuran read buffer untuk response dari backend
# Default: 4KB
read_buffer_size 4kb
# Ukuran write buffer untuk request ke backend
# Default: 4KB
write_buffer_size 4kb
# ═══ Protokol ══════════════════════════════════════════════
# Paksa HTTP/1.1 ke backend (nonaktifkan HTTP/2)
# Berguna jika backend tidak support HTTP/2
versions 1.1
# Atau eksplisit izinkan HTTP/2
# versions 1.1 2
}
}
}
Transport HTTP: Konfigurasi Praktis #
Backend HTTP Biasa (Tanpa TLS) #
# Konfigurasi ringan untuk backend lokal (paling umum)
example.com {
reverse_proxy localhost:3000 {
transport http {
dial_timeout 5s
response_header_timeout 30s
keep_alive 90s
}
}
}
Backend HTTPS dengan Sertifikat Self-Signed #
example.com {
reverse_proxy https://internal-backend:8443 {
transport http {
tls
# Percaya hanya CA internal perusahaan
tls_trusted_ca_certs /etc/ssl/internal-ca.pem
tls_server_name internal-backend.company.internal
dial_timeout 5s
response_header_timeout 30s
}
}
}
Backend dengan Mutual TLS (mTLS) #
mTLS adalah konfigurasi di mana kedua sisi memverifikasi identitas satu sama lain via sertifikat:
example.com {
reverse_proxy https://secure-backend:8443 {
transport http {
tls
# Verifikasi sertifikat backend menggunakan CA ini
tls_trusted_ca_certs /etc/caddy/certs/backend-ca.pem
# Kirim client certificate untuk diverifikasi oleh backend
# Backend harus dikonfigurasi untuk require client cert
tls_client_auth /etc/caddy/certs/caddy-client.pem \
/etc/caddy/certs/caddy-client.key
tls_server_name secure-backend.internal
}
}
}
# Generate client certificate untuk Caddy
openssl req -x509 -newkey rsa:4096 \
-keyout caddy-client.key \
-out caddy-client.pem \
-days 365 -nodes \
-subj "/CN=caddy-proxy/O=Infrastructure"
# Backend perlu dikonfigurasi untuk require dan verify client cert
# (konfigurasi tergantung backend — Node.js, Go, Python, dll.)
FastCGI Transport — Untuk PHP-FPM #
FastCGI adalah protokol komunikasi yang digunakan antara web server dan PHP-FPM. Berbeda dari HTTP, FastCGI tidak sama dengan meneruskan request HTTP biasa.
php-site.example.com {
root * /var/www/php-app
# Menggunakan php_fastcgi (shortcut untuk FastCGI ke PHP)
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
}
# php_fastcgi adalah shortcut untuk:
php-site.example.com {
root * /var/www/php-app
reverse_proxy unix//run/php/php8.3-fpm.sock {
transport fastcgi {
# Script filename yang akan dieksekusi
# {http.request.uri.path} = path file PHP yang diminta
root /var/www/php-app
split .php
# Environment variables yang dikirim ke PHP-FPM
env SERVER_SOFTWARE "caddy"
env SCRIPT_FILENAME "{http.vars.root}{path}"
}
}
}
FastCGI via TCP vs Unix Socket #
example.com {
root * /var/www/html
# Via TCP (lebih mudah untuk Docker/remote)
php_fastcgi localhost:9000
# Via Unix socket (lebih cepat untuk local)
php_fastcgi unix//run/php/php8.3-fpm.sock
# Via Unix socket untuk PHP 8.2
# php_fastcgi unix//run/php/php8.2-fpm.sock
file_server
}
FastCGI dengan Environment Variables Kustom #
example.com {
root * /var/www/html
php_fastcgi unix//run/php/php8.3-fpm.sock {
# Kirim environment variable ke PHP
env APP_ENV "production"
env DB_HOST "localhost"
env REDIS_HOST "localhost:6379"
# Resolve symlinks sebelum menentukan SCRIPT_FILENAME
resolve_root_symlink
# Timeout untuk FastCGI response
read_timeout 30s
write_timeout 30s
# Capture stderr dari PHP (PHP errors akan muncul di Caddy log)
# capture_stderr
}
file_server
}
Tuning Connection Pool untuk High Traffic #
Untuk deployment dengan traffic tinggi, tuning connection pool sangat penting:
high-traffic.example.com {
reverse_proxy backend-1:3000 backend-2:3000 {
transport http {
# Pertahankan lebih banyak koneksi idle
# Mengurangi overhead buat koneksi baru
max_idle_conns_per_host 200
# Perpanjang waktu koneksi idle dipertahankan
# Default 90s kadang terlalu pendek untuk backend yang lambat warm-up
keep_alive 120s
# Timeout yang lebih pendek untuk fail-fast
dial_timeout 3s
# Response header timeout moderat
response_header_timeout 30s
# Buffer yang lebih besar untuk request/response besar
read_buffer_size 8kb
write_buffer_size 8kb
}
}
}
Transport untuk Layanan gRPC #
gRPC menggunakan HTTP/2 secara eksklusif. Caddy bisa menjadi proxy untuk gRPC service:
grpc.example.com {
reverse_proxy h2c://grpc-backend:50051 {
# h2c = HTTP/2 cleartext (tanpa TLS)
transport http {
versions 2
}
}
}
# Atau jika gRPC backend menggunakan TLS
grpc.example.com {
reverse_proxy https://grpc-backend:50051 {
transport http {
tls
versions 2
tls_trusted_ca_certs /etc/caddy/certs/grpc-ca.pem
}
}
}
Debugging Transport Issues #
# Cek apakah backend bisa dijangkau dari server Caddy
curl -v http://localhost:3000/health
# Untuk HTTPS backend
curl -v --cacert /path/to/ca.pem https://internal-backend:8443/health
# Untuk mTLS backend
curl -v \
--cacert /path/to/ca.pem \
--cert /path/to/client.pem \
--key /path/to/client.key \
https://mtls-backend:8443/health
# Lihat log Caddy untuk transport errors
sudo journalctl -u caddy | grep -i "transport\|dial\|timeout\|refused"
# Aktifkan debug logging sementara
# Di Caddyfile: { debug }
# Akan muncul detail koneksi transport
Ringkasan #
- Transport
httpadalah default — cocok untuk backend HTTP dan HTTPS biasa, dengan opsi TLS, timeout, dan connection pool yang bisa dikonfigurasi.- Untuk koneksi ke backend HTTPS dengan sertifikat internal, gunakan
tls_trusted_ca_certsbukantls_insecure_skip_verifydi production.- mTLS (mutual TLS) dikonfigurasi dengan kombinasi
tls_trusted_ca_certsuntuk verifikasi backend dantls_client_authuntuk client certificate Caddy.- Transport
fastcgidigunakan untuk PHP-FPM — gunakan shortcutphp_fastcgiyang sudah mengkonfigurasi semua parameter yang diperlukan.- Untuk high-traffic deployment, tuning
max_idle_conns_per_hostdankeep_alivebisa secara signifikan mengurangi overhead koneksi baru.- gRPC membutuhkan HTTP/2 — gunakan
h2c://untuk gRPC tanpa TLS atau konfigurasi TLS transport denganversions 2untuk gRPC dengan TLS.