Location Block #
Jika server block menentukan site mana yang menangani request, location block menentukan apa yang dilakukan dengan request tersebut berdasarkan URL path-nya. Location block adalah tempat sebagian besar logika routing Nginx ditulis, dan memahami cara kerjanya dengan baik adalah kunci untuk bisa menulis konfigurasi yang benar.
Struktur Dasar #
server {
listen 80;
server_name example.com;
location /images/ {
root /var/www;
# Request ke /images/logo.png → serve /var/www/images/logo.png
}
location /api/ {
proxy_pass http://localhost:3000;
# Request ke /api/users → diteruskan ke backend
}
}
Location block mendefinisikan: “untuk request yang URL path-nya cocok dengan ini, lakukan ini.”
Modifier: Cara Pencocokan yang Berbeda #
Ini adalah bagian yang paling krusial dari location block. Ada empat modifier (dan satu tanpa modifier), masing-masing dengan cara pencocokan yang berbeda:
Tanpa Modifier — Prefix Match #
location /images/ {
# Cocok dengan: /images/, /images/logo.png, /images/2024/photo.jpg
# Tidak cocok dengan: /my-images/, /timages/
}
Tanpa modifier, location melakukan prefix match — URL yang dimulai dengan string yang ditentukan akan cocok.
= — Exact Match
#
location = / {
# Hanya cocok TEPAT dengan /
# Tidak cocok dengan /index.html, /about, dll.
}
location = /favicon.ico {
# Hanya cocok TEPAT dengan /favicon.ico
log_not_found off; # Jangan log jika file tidak ada
access_log off;
}
Exact match berhenti mencari begitu menemukan kecocokan — ini membuatnya sedikit lebih cepat dari prefix match untuk path yang sangat sering diakses.
~ — Regex, Case-Sensitive
#
location ~ \.php$ {
# Cocok dengan file yang diakhiri .php (case-sensitive)
# Cocok: /index.php, /user/profile.php
# Tidak cocok: /index.PHP (huruf besar)
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
include fastcgi_params;
}
~* — Regex, Case-Insensitive
#
location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
# Cocok dengan file gambar, tidak peduli huruf besar/kecil
# Cocok: /logo.jpg, /banner.JPG, /icon.PNG
expires 1y;
add_header Cache-Control "public, immutable";
}
^~ — Prefix Match Prioritas Tinggi
#
location ^~ /static/ {
# Prefix match biasa, tapi jika cocok,
# Nginx TIDAK akan mencoba mencocokkan regex location lain
root /var/www;
}
^~ berguna ketika kamu punya prefix yang harus ditangani secara spesifik dan kamu tidak mau ada regex location yang secara tidak sengaja menangkapnya.
Urutan Prioritas Pencocokan #
Ini adalah urutan yang Nginx gunakan untuk memilih location block:
1. Exact match (=)
→ Jika cocok, langsung gunakan, selesai
2. Prefix match biasa (tanpa modifier)
→ Nginx mencatat kecocokan terpanjang, tapi belum berhenti
3. Jika prefix match terpanjang menggunakan ^~
→ Gunakan itu, selesai (skip regex)
4. Regex match (~ dan ~*), dalam urutan kemunculan di konfigurasi
→ Gunakan regex pertama yang cocok
5. Jika tidak ada regex yang cocok
→ Gunakan prefix match terpanjang dari langkah 2
Contoh konkret untuk memperjelasnya:
server {
location = /exact {
# 1. Exact match — hanya /exact
}
location /prefix/ {
# 2. Prefix match — /prefix/, /prefix/file, dst
}
location ^~ /assets/ {
# 3. Prefix match prioritas tinggi — /assets/ dan subtree-nya
# Jika ini cocok, regex di bawah tidak dicoba
}
location ~* \.(css|js)$ {
# 4. Regex — semua .css dan .js
}
location / {
# 5. Fallback — cocok dengan semua (prefix "/" cocok segalanya)
}
}
Request untuk /assets/app.css:
= /exact→ tidak cocok/prefix/→ tidak cocok/assets/dengan^~→ cocok! — karena ada^~, Nginx stop di sini dan tidak coba regex
Request untuk /style.css:
= /exact→ tidak cocok/prefix/→ tidak cocok/assets/→ tidak cocok~* \.(css|js)$→ cocok! — regex digunakan
try_files: Mencoba Beberapa Opsi #
try_files adalah salah satu directive yang paling sering digunakan dalam location block. Ia mencoba satu per satu opsi yang diberikan dan menggunakan yang pertama berhasil:
location / {
try_files $uri $uri/ =404;
# Coba urutan berikut:
# 1. $uri → apakah ada file yang cocok dengan URL ini?
# 2. $uri/ → apakah ada direktori yang cocok?
# (dan ada index file di dalamnya)
# 3. =404 → jika tidak ada, return 404
}
Untuk aplikasi dengan single-page routing (React, Vue, Angular):
location / {
try_files $uri $uri/ /index.html;
# Jika file/direktori tidak ada, selalu serve index.html
# (biarkan JavaScript router yang handle routing)
}
Untuk aplikasi PHP (WordPress, Laravel):
location / {
try_files $uri $uri/ /index.php?$query_string;
# Jika file tidak ada, teruskan ke index.php (front controller)
}
Nested Location #
Location block bisa bersarang, meski ini jarang diperlukan dan sebaiknya dihindari kecuali benar-benar dibutuhkan karena bisa membingungkan:
location /api/ {
proxy_pass http://api_backend;
# Nested — khusus untuk /api/admin/
location /api/admin/ {
# Batasi akses ke IP internal saja
allow 10.0.0.0/8;
deny all;
proxy_pass http://api_backend;
}
}
Pola Konfigurasi yang Umum #
Static site #
server {
listen 80;
server_name example.com;
root /var/www/html;
location / {
try_files $uri $uri/ =404;
}
# Cache agresif untuk file statis
location ~* \.(css|js|png|jpg|gif|ico|woff2|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Jangan izinkan akses ke file tersembunyi
location ~ /\. {
deny all;
}
}
PHP-FPM (WordPress, Laravel, dll.) #
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
# Blokir akses ke file sensitif
location ~ /\.(ht|git|env) {
deny all;
}
}
Reverse Proxy ke Node.js/Python #
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://localhost: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;
}
# Endpoint health check tidak perlu di-log
location = /health {
proxy_pass http://localhost:3000;
access_log off;
}
}
Kesalahan Umum #
# ANTI-PATTERN: Dua location dengan regex yang saling tumpang tindih
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
location ~ /admin\.php$ {
# ← Ini tidak pernah tercapai!
# /admin.php sudah ditangkap oleh \.php$ di atas
# karena regex dicocokkan dalam urutan kemunculan
allow 192.168.1.0/24;
deny all;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
# BENAR: Taruh yang lebih spesifik lebih dulu
location ~ /admin\.php$ {
allow 192.168.1.0/24;
deny all;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
Ringkasan #
- Modifier menentukan cara pencocokan:
=exact, tanpa modifier prefix,^~prefix prioritas tinggi,~regex case-sensitive,~*regex case-insensitive.- Urutan prioritas: exact → prefix terpanjang (sambil ingat
^~) → regex (urutan kemunculan) → prefix terpanjang fallback.try_filesmencoba beberapa opsi berurutan — sangat berguna untuk SPA, PHP, dan static site.- Untuk regex yang saling tumpang tindih, urutan kemunculan di konfigurasi menentukan mana yang menang — taruh yang lebih spesifik lebih dulu.
location ~ /\.untuk blokir akses ke file tersembunyi (.env,.git,.htaccess) adalah praktik keamanan yang penting.