Transport

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 http adalah 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_certs bukan tls_insecure_skip_verify di production.
  • mTLS (mutual TLS) dikonfigurasi dengan kombinasi tls_trusted_ca_certs untuk verifikasi backend dan tls_client_auth untuk client certificate Caddy.
  • Transport fastcgi digunakan untuk PHP-FPM — gunakan shortcut php_fastcgi yang sudah mengkonfigurasi semua parameter yang diperlukan.
  • Untuk high-traffic deployment, tuning max_idle_conns_per_host dan keep_alive bisa secara signifikan mengurangi overhead koneksi baru.
  • gRPC membutuhkan HTTP/2 — gunakan h2c:// untuk gRPC tanpa TLS atau konfigurasi TLS transport dengan versions 2 untuk gRPC dengan TLS.

← Sebelumnya: Proxy Headers   Berikutnya: Proxy Cache →

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