Location Block

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_files mencoba 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.

← Sebelumnya: Server Block   Berikutnya: Variabel Bawaan →

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