Nginx (dibaca "engine-x") adalah web server: program yang menunggu request HTTP di port 80 (dan 443 untuk HTTPS), lalu menjawabnya, entah dengan file dari disk, entah dengan meneruskannya ke app di belakangnya. Bayangin resepsionis gedung perkantoran. Gedungnya satu alamat, tapi kantornya banyak. Tamu datang, resepsionis melihat nama kantor yang dicari (di nginx: header Host), lalu ruangan yang dituju (di nginx: path URL), dan mengantarnya ke tempat yang benar.
🧪 Tebakan cepat: config catatan.example.com punya
location /lampiran/(folder lampiran user) danlocation ~* \.(jpg|jpeg|png|svg|css|js)$(cache 30 hari untuk gambar dan aset). RequestGET /lampiran/a4c2e9f1.jpgditangani location yang mana? Tebak dulu, jawabannya ada di bagian "Urutan nginx memilih location".
Memasang nginx di web-1
Di web-1 (Ubuntu 24.04), sudo apt install nginx memasangnya, dan systemd langsung menjalankannya. curl -I http://localhost (header saja) menjawab HTTP/1.1 200 OK dengan Server: nginx/1.24.0 (Ubuntu): itu halaman bawaan "Welcome to nginx!".
/etc/nginx/nginx.confadalah config utama. Dia meng-include semua file di/etc/nginx/sites-enabled/.- Config tiap situs disimpan di
/etc/nginx/sites-available/, lalu dinyalakan dengan symlink (jalan pintas) disites-enabled/. Ubuntu sudah menaruhdefaultdi sana. Log-nya di/var/log/nginx/.
Server block: satu situs, satu blok
Situs catatan-api di catatan.example.com punya file statis: halaman depan index.html dan asetnya di /var/www/catatan, plus lampiran yang di-upload user. App Express-nya baru disambungkan di pelajaran berikutnya (reverse proxy); sekarang nginx melayani file statisnya dulu. Config-nya ditulis di /etc/nginx/sites-available/catatan:
server {
listen 80;
listen [::]:80;
server_name catatan.example.com www.catatan.example.com;
root /var/www/catatan;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
server { ... }adalah server block: satu situs. Satu nginx bisa memegang banyak server block.listen 80;port yang didengarkan (IPv4).listen [::]:80;sama untuk IPv6.server_namenama domain yang dilayani blok ini, dicocokkan dengan headerHostdari browser.rootfolder tempat file situs: request/logo.svgdicari di/var/www/catatan/logo.svg.indexfile yang dikirim saat yang diminta sebuah folder, misalnya/.location / { ... }aturan untuk path yang diawali/.try_files $uri $uri/ =404;artinya: kirim file-nya kalau ada, folder-nya (denganindex-nya) kalau ada, kalau gak ada keduanya jawab404. SPA biasanya menulis/index.htmldi posisi terakhir, supaya semua path jatuh ke halaman yang sama.- Tiap directive (perintah) diakhiri
;, dan tiap blok dibungkus{ }.
Nyalakan situsnya dengan sudo ln -s /etc/nginx/sites-available/catatan /etc/nginx/sites-enabled/, matikan halaman bawaan dengan sudo rm /etc/nginx/sites-enabled/default, lalu uji dan terapkan (bagian terakhir).
Di latihan, kamu menyusun teks server block dari object { port, serverName, root, locations }. Baris di dalam server diindentasi 4 spasi, isi location 8 spasi, dan tiap directive diakhiri ;. Untuk { port: 80, serverName: "myapp.com", root: "/var/www/html", locations: [{ path: "/", directive: "try_files $uri /index.html" }] } hasilnya persis:
server {
listen 80;
server_name myapp.com;
root /var/www/html;
location / {
try_files $uri /index.html;
}
}
Nginx memilih server block dari port dan Host
Browser yang membuka http://catatan.example.com tersambung ke IP web-1, 203.0.113.10, port 80, lalu mengirim Host: catatan.example.com. Nginx mengambil semua server block yang listen di port itu dan mencocokkan Host dengan server_name mereka. Kalau gak ada yang cocok, dia memakai default server port itu: yang ditandai default_server, atau server block pertama kalau gak ada yang ditandai.
Di bawah server block catatan, web-1 punya satu blok penampung:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 444;
}
| Request | Host |
Server block | Hasil |
|---|---|---|---|
curl -I http://catatan.example.com/ |
catatan.example.com |
catatan | 200 OK |
curl -I http://www.catatan.example.com/ |
www.catatan.example.com |
catatan | 200 OK |
curl -I http://203.0.113.10/ |
203.0.113.10 |
default | koneksi diputus |
server_name _ cuma nama yang gak mungkin cocok. return 444 kode khusus nginx: tutup koneksi tanpa jawaban sama sekali, jadi curl menulis curl: (52) Empty reply from server. Bot yang memindai IP acak gak dapat apa-apa.
Urutan nginx memilih location
Server block catatan yang lengkap, sama dengan yang ada di Lab:
location = /favicon.ico { access_log off; log_not_found off; }
location /lampiran/ {
alias /srv/catatan-api/storage/lampiran/;
}
location ~* \.(jpg|jpeg|png|svg|css|js)$ { expires 30d; }
location / {
try_files $uri $uri/ =404;
}
= /favicon.ico: cocok persis path itu saja.access_log offsupaya log gak penuh request favicon./lampiran/: prefix, cocok untuk semua path yang diawali/lampiran/.aliasmengganti bagian/lampiran/dengan folder upload catatan-api, jadi/lampiran/a4c2e9f1.jpgdibaca dari/srv/catatan-api/storage/lampiran/a4c2e9f1.jpg.~*: regex (pola teks) yang gak peka huruf besar-kecil.~versi yang peka.expires 30dmenyuruh browser menyimpan file itu 30 hari.
Nginx memilih location dengan empat langkah. Urutan location prefix di file gak berpengaruh, tapi urutan regex berpengaruh:
- Ada
=yang cocok persis? Pakai itu, selesai. - Cari prefix terpanjang yang cocok. Kalau prefix itu ditandai
^~, pakai itu, selesai. - Cek regex berurutan sesuai tulisan di file. Regex pertama yang cocok menang.
- Gak ada regex yang cocok? Pakai prefix terpanjang dari langkah 2.
| Path | Location terpilih | Hasil |
|---|---|---|
/favicon.ico |
= /favicon.ico (langkah 1) |
200, favicon |
/ |
/ (langkah 4) |
200, index.html |
/catatan/12 |
/ (langkah 4) |
404, API-nya belum disambungkan |
/assets/app.3f9a1c.js |
regex (langkah 3) | 200, cache 30 hari |
/lampiran/a4c2e9f1.jpg |
regex (langkah 3) | 404 Not Found |
Lihat baris terakhir. Di langkah 2, prefix terpanjangnya /lampiran/, tapi dia prefix biasa, jadi nginx lanjut ke langkah 3, dan .jpg cocok dengan regex. Regex menang, lalu nginx mencari /var/www/catatan/lampiran/a4c2e9f1.jpg, yang gak ada: 404. Itu jawaban tebakannya. Perbaikannya satu tanda: location ^~ /lampiran/. Sekarang langkah 2 berhenti di /lampiran/, dan regex gak pernah dicek.
Cek dulu dengan nginx -t, baru reload
Tiap kali config diubah, uji dulu, baru terapkan:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl reload nginx
Kalau titik koma setelah root /var/www/catatan (baris 5) hilang, nginx membaca terus sampai titik koma berikutnya, jadi dia melihat root /var/www/catatan index index.html;, satu directive dengan tiga argumen:
$ sudo nginx -t
nginx: [emerg] invalid number of arguments in "root" directive in /etc/nginx/sites-enabled/catatan:6
nginx: configuration file /etc/nginx/nginx.conf test failed
nginx -t(test) mengecek semua config tanpa mengubah apa pun yang sedang jalan. Nomor baris di pesan error adalah tempat nginx sadar ada yang salah, sering satu baris setelah kesalahannya.sudo systemctl reload nginx(sama dengansudo nginx -s reload) membaca config baru tanpa memutus koneksi yang sedang jalan. Kalau config-nya rusak, reload ditolak dan config lama tetap melayani.sudo systemctl restart nginxmematikan nginx lalu menyalakannya lagi. Dengan config rusak, nginx gak bisa nyala lagi, dan catatan.example.com down.
⚠️ Jebakan yang sering ketemu
- Lupa titik koma. Pesannya bisa
invalid number of argumentsataudirective "..." is not terminated by ";", dan nomor barisnya sering menunjuk baris sesudahnya. Cek baris di atasnya juga. - Regex mengambil alih folder. Prefix biasa kalah dari regex yang cocok. Untuk folder yang gak boleh diganggu regex, pakai
^~. - Restart tanpa
nginx -t. Biasakansudo nginx -t && sudo systemctl reload nginx: reload cuma jalan kalau test-nya lolos. - Dua
default_server. Lupa menghapus symlinkdefaultbikinnginx: [emerg] a duplicate default server for 0.0.0.0:80 in /etc/nginx/sites-enabled/default:22. Satu port cuma boleh punya satu default server.
TL;DR: Nginx adalah web server (dan reverse proxy, pelajaran berikutnya) yang menjawab request di port 80 dan 443. Config tiap situs ditulis di sites-available, dinyalakan lewat symlink di sites-enabled. Server block (server { listen; server_name; root; location }) dipilih dari port dan header Host; yang gak cocok jatuh ke default_server. Location dipilih dengan urutan: = persis, lalu prefix terpanjang (berhenti kalau ^~), lalu regex ~/~* sesuai urutan di file, lalu prefix terpanjang tadi. Tiap directive diakhiri ;. Selalu sudo nginx -t dulu, lalu sudo systemctl reload nginx (atau nginx -s reload), yang gak memutus koneksi dan menolak config rusak.