Bentuk Paling Sederhana
server {
listen 80;
server_name api.contoh.id;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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 $scheme;
}
}
Kenapa Header Itu Wajib
Begitu Nginx berdiri di depan aplikasi, aplikasi kehilangan seluruh konteks tentang klien. Yang dilihatnya hanyalah koneksi dari 127.0.0.1 melalui HTTP biasa. Empat header di atas mengembalikan konteks yang hilang itu.
$host # nama host yang diminta klien $remote_addr # alamat IP klien $proxy_add_x_forwarded_for # rantai X-Forwarded-For + IP klien $scheme # http atau https di sisi klien
Aplikasi yang memaksa HTTPS melihat koneksi masuk sebagai http — karena memang begitu antara Nginx dan aplikasi. Ia lalu mengalihkan ke https://, permintaan kembali ke Nginx, diteruskan lagi sebagai HTTP, dan dialihkan lagi. Peramban akhirnya menyerah dengan ERR_TOO_MANY_REDIRECTS. Header ini memberi tahu aplikasi bahwa klien sudah memakai HTTPS.
Slash di Akhir proxy_pass Mengubah Segalanya
location /api/ {
proxy_pass http://backend; # TANPA slash
}
# /api/pengguna → http://backend/api/pengguna (path utuh)
location /api/ {
proxy_pass http://backend/; # DENGAN slash
}
# /api/pengguna → http://backend/pengguna (/api/ dipotong)
Bila proxy_pass berisi path apa pun — termasuk hanya / — Nginx mengganti bagian URI yang cocok dengan location. Bila hanya berisi host dan port, URI diteruskan apa adanya. Ini penyebab umum aplikasi hulu menerima path ganda seperti /api/api/pengguna.
Batas Waktu yang Perlu Disetel
proxy_connect_timeout 5s; # membuka koneksi ke hulu proxy_send_timeout 60s; # mengirim permintaan ke hulu proxy_read_timeout 60s; # menunggu balasan dari hulu proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k;
proxy_connect_timeout sebaiknya pendek — bila hulu tidak menjawab jabat tangan dalam 5 detik, ia memang sedang bermasalah dan menunggu lebih lama hanya menahan worker. Sebaliknya proxy_read_timeout harus mengikuti permintaan terlama yang wajar di aplikasi.
Buffering: Perisai untuk Klien Lambat
Dengan proxy_buffering on, Nginx membaca balasan dari hulu secepat mungkin, menyimpannya, lalu menyuapkan pelan-pelan ke klien. Aplikasi hulu dibebaskan setelah beberapa milidetik, bukan menunggu klien di jaringan lambat selesai mengunduh.
Untuk Server-Sent Events, streaming log, atau balasan bertahap, buffering menahan data sampai penuh sehingga klien seolah tidak menerima apa-apa. Matikan hanya pada location tersebut, bukan secara global.
location /stream/ {
proxy_pass http://backend;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 24h;
}
WebSocket
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
}
Blok map diperlukan supaya header Connection hanya bernilai upgrade ketika permintaan memang ingin naik ke WebSocket, dan close untuk permintaan HTTP biasa yang melewati location yang sama.