Menyiapkan HTTPS di RoadRunner: mengaktifkan http.ssl dengan sertifikat langsung, atau menempatkan Nginx dan Caddy sebagai reverse proxy di depan RoadRunner, plus praktik deployment TLS production yang aman dan benar.

Setelah di episode 14 kita memastikan worker-safe, pada episode kali ini kita mengamankan jalur masuk: TLS/HTTPS dan reverse proxy. Di production, kalian punya dua pilihan — RoadRunner menangani TLS langsung, atau ditaruh di belakang Nginx/Caddy yang menangani TLS.
Mengapa episode ini penting? Karena TLS bukan sekadar "aktifkan sertifikat". Ada keputusan arsitektur: siapa yang menghentikan TLS, bagaimana header diteruskan ke PHP, dan bagaimana reverse proxy berinteraksi dengan pool. Salah konfigurasi sering menghasilkan mixed content, loop redirect, atau header salah yang membuat aplikasi (dan user) menderita.
| Opsi | Kelebihan | Kekurangan |
|---|---|---|
| RR langsung TLS | Sederhana, satu proses | Sertifikat diurus sendiri |
| Reverse proxy | TLS, rate limit, WAF, static di proxy | Satu komponen tambahan |
Kedua opsi valid; pemilihan bergantung tim: kalau kalian sudah punya Nginx/Caddy, taruh di depan. Kalau mau minimalis, aktifkan TLS di RoadRunner.
Aktifkan http.ssl dengan path sertifikat dan key:
http:
address: 0.0.0.0:8080
ssl:
cert: /etc/ssl/domain.crt
key: /etc/ssl/domain.key
middleware: ["gzip"]Perhatikan: ssl.cert dan ssl.key menunjuk file di server — RoadRunner membaca keduanya saat start. Untuk sertifikat dari Let's Encrypt, pastikan path menunjuk ke file yang diperbarui certbot (atau atur reload). Contoh dengan chain penuh (leaf + intermediate):
cat /etc/letsencrypt/live/domain/fullchain.pem > /etc/ssl/domain.crt
cp /etc/letsencrypt/live/domain/privkey.pem /etc/ssl/domain.keyWarning
Jangan pernah memakai self-signed certificate di production tanpa alasan kuat — browser akan memblokir, dan traffic yang "aman" dengan cert yang ditolak browser tetap bisa di-man-in-the-middle. Untuk produksi, gunakan Let's Encrypt (free) atau CA komersial.
Nginx menangani TLS dan meneruskan HTTP ke RoadRunner. Blok server kunci:
server {
listen 443 ssl;
server_name domain.com;
ssl_certificate /etc/letsencrypt/live/domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
# Static: biarkan Nginx yang melayani
location /assets/ {
alias /var/www/app/public/assets/;
expires 1y;
add_header Cache-Control "public, immutable";
}
}Poin penting:
proxy_pass menunjuk ke http.address RoadRunner.Host, X-Real-IP, X-Forwarded-For, dan X-Forwarded-Proto wajib diteruskan agar aplikasi tahu identitas client yang sebenarnya (bukan IP Nginx).proxy_set_header Connection ""; penting untuk mempertahankan koneksi HTTP/1.1 antara Nginx dan RoadRunner (mengurangi overhead handshake).sendfile di level OS).Saat memakai reverse proxy, aplikasi PHP menerima request yang sudah "diteruskan". Framework membaca header forwarded untuk membangun URL yang benar:
$scheme = $request->getHeaderLine('X-Forwarded-Proto') ?: 'http';
$fullUrl = $scheme . '://' . $request->getHeaderLine('Host') . $request->getUri()->getPath();Di Laravel, set trusted proxies (seperti di config) supaya url() dan redirect menghormati X-Forwarded-Proto — jika tidak, aplikasi akan memaksa redirect HTTPS selamanya (loop redirect) karena mengira request masih HTTP.
Danger
Hanya percaya header X-Forwarded-* bila request memang datang dari proxy yang kalian kendalikan. Jika RoadRunner bisa diakses langsung dari publik tanpa proxy, attacker bisa memalsukan X-Forwarded-For untuk mem-bypass rate limit atau IP-based logic. Di RoadRunner, plugin reverse-proxy (trusted proxy) membatasi ini — kita bahas di episode 17.
RoadRunner mendukung HTTP/2 dan (bila TLS aktif dan didukung binary) HTTP/3. Keuntungan utama: multiplexing request pada satu koneksi dan header compression — sangat membantu aplikasi dengan banyak aset. Pastikan klien dan proxy di depan tidak memblokir protokol ini; di Caddy/Nginx sisi proxy, aktifkan HTTP/2 dengan satu baris listen ... http2.
Verifikasi protokol yang dipakai:
curl -sI --http2 https://domain.com/ | head -5| Item | Status yang benar |
|---|---|
| Sertifikat valid dan belum kedaluwarsa | openssl s_client -connect domain:443 -servername domain |
| Redirect HTTP → HTTPS | Server block return 301 https://$host$request_uri; |
| Header forwarded diteruskan | Proxy mengirim X-Forwarded-Proto |
Aplikasi memakai X-Forwarded-Proto | Laravel trusted proxies aktif |
| Tidak ada mixed content | Semua aset dilayani HTTPS |
| Port RPC tidak ter-expose | RPC hanya 127.0.0.1 |
Pada episode 15 ini, kalian telah menyiapkan HTTPS dengan dua arsitektur.
Inti yang harus dibawa pulang:
http.ssl dengan cert/key untuk TLS langsung.X-Forwarded-* wajib diteruskan dan hanya dipercaya dari proxy kalian.curl -I dan openssl s_client.Di episode 16 selanjutnya, kita belajar gRPC plugin — mendefinisikan service lewat file .proto, menjalankan gRPC server PHP dengan package roadrunner-grpc, dan menguji dengan client gRPC. Sampai jumpa di episode 16!