Linux : Nginx Dasar dan Virtual Host: Difference between revisions
Artikel baru: Nginx dasar dan virtual host (konsep tiga lapis pemilihan situs) ย |
m Protected "Linux : Nginx Dasar dan Virtual Host": Proteksi editorial: edit/move sysop ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite)) ย |
(No difference)
| |
Latest revision as of 07:03, 8 November 2026
๐ฏ Tujuan
Setelah membaca artikel ini, kamu bisa menjelaskan bagaimana Nginx memilih situs yang menjawab sebuah permintaan, membuat dua situs berbeda di satu alamat IP, dan tahu di lapis mana masalah "yang muncul malah situs lain" sebenarnya terjadi.
Artikel ini bukan panduan instalasi. Kalau kamu baru pertama kali memasang Nginx, mulai dari halaman Debian : Konfigurasi Web Server (Nginx). Di sini kita membedah proses keputusan di balik layar.
๐ Konteks nyata
Bayangkan satu gedung dengan satu alamat. Tamu datang ke resepsionis, menyebut nama yang dituju, lalu diarahkan ke lantai yang tepat.
Nginx bekerja seperti resepsionis itu. Alamat gedungnya adalah IP dan port, nama yang disebut tamu adalah header Host, dan lantai tujuan adalah server block.
- ๐ฅ Kasus nyata: Sebuah SMK menggabungkan wiki, aplikasi ujian, dan situs profil sekolah di satu server. Saat "merapikan folder", seorang teknisi menghapus symlink di
/etc/nginx/sites-enabled/. Ketiga domain langsung menampilkan halaman default Nginx selama dua hari, dan panitia menuduh DNS sekolah rusak. Penyebab sebenarnya ketahuan dalam 10 detik lewatnginx -T: konfigurasi yang dipakai Nginx memang tidak lagi memuat ketiga server block itu.
๐ง Konsep singkat
Nginx bukan program yang menyalakan satu utas (thread) untuk setiap pengunjung. Ada satu proses master yang membaca konfigurasi, lalu beberapa proses worker yang melayani koneksi.
Karena worker bekerja dengan model event, satu worker bisa menangani ribuan koneksi yang menunggu tanpa kehabisan utas. Analoginya: satu pramuniaga yang melayani banyak meja sekaligus, bukan satu pramuniaga yang berdiri diam di tiap meja.
๐น Tiga lapis keputusan
Setiap permintaan HTTP melewati tiga pintu berurutan. Kalau satu pintu salah, gejala yang muncul bisa terlihat seperti masalah di pintu lain.
| Lapis | Yang dibaca | Gejala kalau salah |
|---|---|---|
| Soket | alamat IP dan port di listen |
koneksi ditolak, atau situs lain yang menjawab |
| Nama | header Host lawan server_name |
muncul situs default, bukan situs yang dituju |
| Path | URI lawan location |
404, 403, atau file dari folder yang salah |
Aturan praktisnya: buktikan lapis pertama dulu, jangan langsung mengubah isi halaman. Situs yang "salah tampil" hampir tidak pernah disebabkan oleh file HTML-nya.
๐น Virtual host adalah server block
Satu blok server { ... } mewakili satu situs. Di dalamnya ada listen, server_name, dan aturan lain seperti root serta location.
Ada dua cara memisahkan situs:
- Berbasis IP โ tiap situs punya alamat IP sendiri. Boros, karena IP publik terbatas.
- Berbasis nama โ semua situs berbagi satu IP, dibedakan dari header
Host. Inilah cara kerja hampir semua hosting.
- ๐ Angka penting: Satu IP publik bisa melayani ratusan nama domain. Yang membedakan hanya header
Host, satu baris teks yang dikirim browser di setiap permintaan.
Untuk HTTPS, nama domain dibaca lebih awal lagi: saat handshake TLS lewat SNI, sebelum header HTTP dikirim. Karena itu sertifikat bisa dipilih per situs walau IP-nya sama.
๐น default_server milik port, bukan nama
Ini sumber kebingungan paling sering. Dokumentasi resmi Nginx menyebut tegas: *default server adalah properti dari port listen, bukan properti server_name*.
Artinya:
- Kalau tidak ada
default_server, blokserverpertama pada port itu yang jadi default. - Kalau header
Hosttidak cocok dengan nama mana pun, permintaan jatuh ke default server. server_name _;yang sering ditempel dari internet bukan wildcard. Itu cuma nama domain tidak valid yang tidak akan pernah cocok dengan nama asli.
Catch-all yang benar adalah menggabungkan keduanya:
server {
listen 8080 default_server;
server_name _;
return 444;
}
Kode 444 adalah kode non-standar milik Nginx: koneksi ditutup tanpa jawaban sama sekali. Fungsinya menolak permintaan yang datang langsung ke IP tanpa nama domain yang sah.
- โ ๏ธ Hati-hati: Dua blok dengan
default_serverdi port yang sama membuat Nginx menolak start dengan pesanduplicate default server. Tidak ada yang menang diam-diam, konfigurasinya memang batal dimuat.
๐น Urutan pencocokan server_name
Kalau ada beberapa nama di port yang sama, Nginx mencari dengan urutan prioritas berikut, dan berhenti pada yang pertama cocok:
- Nama persis, misalnya
wiki.lab. - Wildcard berawalan bintang paling panjang, misalnya
*.lab. - Wildcard berakhiran bintang paling panjang, misalnya
mail.*. - Regex pertama yang cocok, sesuai urutan di file.
Nama persis disimpan di tabel hash, jadi pencariannya cepat. Regex dicek satu per satu, sehingga paling lambat dan tidak skalabel untuk jumlah nama besar.
- ๐ Angka penting: Kalau nama domain terlalu panjang untuk tabel hash bawaan, Nginx menolak start dengan pesan
could not build server_names_hash, you should increase server_names_hash_bucket_size: 32. Solusinya menaikkan nilai itu ke pangkat dua berikutnya, misalnya 64.
Nama yang ditulis dua kali tidak membuat Nginx gagal start. Ia hanya memberi peringatan conflicting server name "...", ignored dan memakai yang pertama. Sisa bloknya jadi konfigurasi mati yang menipu saat dibaca.
๐น Urutan pencocokan location
Setelah server block terpilih, Nginx memilih location untuk URI-nya. Aturannya berlapis, bukan dari atas ke bawah:
- Cari semua prefix, ingat yang paling panjang.
- Kalau prefix terpanjang memakai
^~, regex tidak dicek sama sekali. - Kalau tidak, regex dicek berurutan dan yang pertama cocok menang.
- Kalau tidak ada regex yang cocok, pakai prefix terpanjang tadi.
Modifier = berarti harus sama persis dan pencarian langsung selesai. Inilah contoh resmi dari dokumentasi Nginx:
| Permintaan | Location yang menang |
|---|---|
/ |
location = /
|
/index.html |
location /
|
/documents/document.html |
location /documents/
|
/images/1.gif |
location ^~ /images/
|
/documents/1.jpg |
location ~* \.(gif|jpg|jpeg)$
|
Perhatikan baris terakhir: /documents/1.jpg tetap masuk ke regex walau prefix /documents/ lebih spesifik. Itulah sebabnya urutan file tidak menentukan, dan sebabnya ^~ ada: untuk mengunci sebuah folder agar tidak direbut regex.
๐น root dan alias bukan sinonim
root menempelkan URI ke path. alias mengganti bagian yang cocok.
Dengan root /data/w3; di dalam location /i/, permintaan /i/top.gif dilayani dari /data/w3/i/top.gif.
Dengan alias /data/w3/images/; di location /i/, permintaan yang sama dilayani dari /data/w3/images/top.gif โ tanpa tambahan i/.
- โ ๏ธ Hati-hati:
aliasbekerja sebagai penggantian teks. Kalaulocation /i/dipasangkanalias /data/w3/imagestanpa garis miring penutup, hasilnya/data/w3/images+top.gif=/data/w3/imagestop.gif. File tidak ada, halaman jadi 404, padahal folder dan filenya benar.
๐น index, try_files, dan satu putaran tambahan
Kalau URI berakhir dengan garis miring, Nginx mencari file indeks sesuai direktif index. Bila index.html tidak ada tapi index.php ada, Nginx melakukan internal redirect ke /index.php lalu mencari location lagi dari awal.
Karena itu satu permintaan bisa berpindah location. Kalau hasilnya aneh, ingat bahwa location kedua yang menentukan, bukan yang pertama.
try_files memeriksa file berurutan dan memakai yang pertama ditemukan. Garis miring di akhir berarti memeriksa direktori, dan parameter terakhir adalah tujuan redirect internal atau kode error.
location / {
try_files $uri $uri/ /index.html;
}
๐งฉ Istilah penting
| Istilah | Arti sederhana |
|---|---|
| Server block | Satu blok server { } yang mewakili satu situs
|
| Virtual host | Istilah umum untuk situs yang berbagi satu server fisik |
Header Host |
Nama domain yang diminta browser, dikirim di setiap permintaan |
server_name |
Daftar nama yang dilayani sebuah server block |
default_server |
Situs penampung bila tidak ada nama yang cocok |
location |
Aturan berdasarkan potongan URI |
root |
Folder dasar yang ditambahi URI |
alias |
Path pengganti untuk location tertentu |
try_files |
Daftar kandidat file yang dicoba berurutan |
| SNI | Cara browser menyebut nama domain saat handshake TLS |
| Reload | Memuat ulang konfigurasi tanpa memutus koneksi yang sedang jalan |
| Upstream | Kumpulan server aplikasi di belakang Nginx |
๐ง Praktik: dua situs di satu server
Lab ini memakai port 8080 supaya tidak bentrok dengan web server lain yang mungkin sudah memakai port 80 di komputermu.
๐น Langkah 1: potret keadaan awal
nginx -v
ss -lntp | grep -E ':80|:8080'
sudo nginx -T > /tmp/nginx-awal.txt
wc -l /tmp/nginx-awal.txt
nginx -T mencetak konfigurasi gabungan yang benar-benar dipakai, termasuk hasil include. Simpan potret ini; nanti kita bandingkan setelah menambah situs.
- ๐งช Uji cepat: Kalau
nginx -Tgagal, jangan lanjut. Perbaikkan dulu error yang disebutkan, karena semua langkah berikutnya bergantung pada konfigurasi yang valid.
๐น Langkah 2: siapkan dua web root
sudo mkdir -p /srv/www/wiki.lab /srv/www/ujian.lab
printf 'WIKI TKJ\n' | sudo tee /srv/www/wiki.lab/index.html
printf 'UJIAN ONLINE\n' | sudo tee /srv/www/ujian.lab/index.html
sudo chown -R www-data:www-data /srv/www
sudo chmod 755 /srv/www /srv/www/wiki.lab /srv/www/ujian.lab
Dua folder, dua isi berbeda. Ini penting: kalau isinya sama, kamu tidak bisa membuktikan situs mana yang menjawab.
๐น Langkah 3: tulis dua server block
server {
listen 8080;
server_name wiki.lab;
root /srv/www/wiki.lab;
index index.html;
access_log /var/log/nginx/wiki.access.log;
error_log /var/log/nginx/wiki.error.log;
}
server {
listen 8080;
server_name ujian.lab;
root /srv/www/ujian.lab;
index index.html;
access_log /var/log/nginx/ujian.access.log;
error_log /var/log/nginx/ujian.error.log;
}
Simpan sebagai /etc/nginx/sites-available/wiki-lab.conf dan /etc/nginx/sites-available/ujian-lab.conf. Pada paket Debian dan Ubuntu, folder sites-available adalah gudang konfigurasi, sedangkan sites-enabled adalah yang dibaca nginx.conf lewat include.
๐น Langkah 4: aktifkan lewat symlink
sudo ln -s /etc/nginx/sites-available/wiki-lab.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/ujian-lab.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
nginx -t menguji sintaks tanpa mengubah apa pun. reload memuat konfigurasi baru dengan mulus: worker lama menyelesaikan permintaan yang sedang berjalan, worker baru memakai konfigurasi terkini.
- ๐ก Tips: Biasakan urutan
nginx -tlalureload, bukanrestart. Restart memutus koneksi aktif dan tidak perlu untuk perubahan konfigurasi biasa.
๐น Langkah 5: uji tanpa menyentuh DNS
curl -s http://127.0.0.1:8080/ -H "Host: wiki.lab"
curl -s http://127.0.0.1:8080/ -H "Host: ujian.lab"
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/
Baris pertama harus mencetak WIKI TKJ, baris kedua UJIAN ONLINE. Perintah ketiga sengaja tanpa Host yang cocok, jadi ia jatuh ke default server โ yaitu blok pertama pada port 8080.
Kalau kamu ingin menguji seperti browser sungguhan tanpa mengubah /etc/hosts, pakai --resolve:
curl -s --resolve ujian.lab:8080:127.0.0.1 http://ujian.lab:8080/
๐น Langkah 6: pasang penolak sebagai default
server {
listen 8080 default_server;
server_name _;
return 444;
}
Simpan sebagai sites-available/tolak-lab.conf, buat symlink, lalu uji ulang:
sudo ln -s /etc/nginx/sites-available/tolak-lab.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
curl -sv -H "Host: tidak-ada.lab" http://127.0.0.1:8080/ 2>&1 | tail -3
Hasil yang diharapkan: koneksi ditutup tanpa balasan, dan curl melaporkan Empty reply from server. Permintaan ke wiki.lab dan ujian.lab tetap normal karena namanya cocok persis.
- ๐ Angka penting: Kode 444 tidak ada di standar HTTP. Browser hanya melihat koneksi terputus. Efek sampingnya: alat monitoring sederhana bisa melaporkan "server mati" padahal Nginx sehat dan sedang menolak.
๐น Langkah 7: buktikan siapa yang menang di location
server {
listen 8081;
server_name peta.lab;
root /srv/www/peta.lab;
default_type text/plain;
location = / { return 200 "A-halaman-depan"; }
location / { return 200 "B-prefix-umum"; }
location ^~ /gambar/ { return 200 "D-prefix-keras"; }
location ~* \.(jpg|png)$ { return 200 "E-regex-gambar"; }
}
Uji tiga URI berikut:
curl -s -H "Host: peta.lab" http://127.0.0.1:8081/
curl -s -H "Host: peta.lab" http://127.0.0.1:8081/gambar/logo.jpg
curl -s -H "Host: peta.lab" http://127.0.0.1:8081/dokumen/logo.jpg
Hasilnya berurutan: A-halaman-depan, D-prefix-keras, E-regex-gambar. Sekarang hapus tanda ^~ dari blok gambar, reload, lalu ulangi permintaan kedua. Hasilnya berubah menjadi E-regex-gambar.
Itu bukti bahwa regex mengalahkan prefix, kecuali prefix dikunci dengan ^~.
๐น Langkah 8: buktikan root berbeda dari alias
sudo mkdir -p /srv/www/peta.lab/isi/r
printf 'ROOT\n' | sudo tee /srv/www/peta.lab/isi/r/top.txt
printf 'ALIAS\n' | sudo tee /srv/www/peta.lab/isi/top.txt
Tambahkan dua location ini ke server block tadi:
location /r/ { root /srv/www/peta.lab/isi; }
location /a/ { alias /srv/www/peta.lab/isi/; }
Setelah reload, /r/top.txt mencetak ROOT dan /a/top.txt mencetak ALIAS. Keduanya menunjuk folder yang sama, tapi aturan penggabungan path-nya berbeda.
๐น Langkah 9: bersihkan lab
sudo rm -f /etc/nginx/sites-enabled/wiki-lab.conf \
/etc/nginx/sites-enabled/ujian-lab.conf \
/etc/nginx/sites-enabled/tolak-lab.conf \
/etc/nginx/sites-enabled/peta-lab.conf
sudo nginx -t && sudo systemctl reload nginx
sudo nginx -T | grep -c "server_name wiki.lab"
Angka terakhir harus 0. Kalau masih 1, symlink lain masih menunjuk file yang sama dan situsnya belum benar-benar dilepas.
๐ญ Dipakai di dunia kerja
- Sekolah: satu server untuk wiki, aplikasi ujian, dan situs profil. Server block memisahkan ketiganya tanpa perlu tiga IP publik atau tiga mesin.
- Kantor dan UMKM: Nginx berdiri di depan aplikasi kasir atau absensi sebagai reverse proxy, sehingga aplikasi internal tidak diekspos langsung ke internet.
- Hosting bersama: ribuan domain berbagi satu IP, dibedakan lewat
server_name. Inilah alasan satu IP bisa melayani banyak pelanggan. - ISP dan warnet: portal login, halaman status, dan billing sering berada di server yang sama dengan nama berbeda.
- Industri dan e-commerce: dua server block atau
upstreamberbobot dipakai untuk mengarahkan sebagian trafik ke versi baru sebelum dirilis penuh. - Operasional DevOps: konfigurasi situs disimpan di git, diuji dengan
nginx -tdi pipeline, lalu di-reloadtanpa memutus pengguna.
โ Verifikasi
| Perintah | Hasil yang diharapkan |
|---|---|
sudo nginx -t |
syntax is ok dan test is successful
|
sudo nginx -T |
konfigurasi gabungan memuat semua server block aktif |
ss -lntp | grep 8080 |
ada proses nginx yang mendengarkan port itu
|
curl -H "Host: wiki.lab" |
isi situs wiki, bukan halaman default |
curl tanpa Host cocok |
ditolak 444 atau masuk default server yang memang disengaja |
tail /var/log/nginx/wiki.access.log |
baris permintaan uji tercatat di log situs yang benar |
sudo systemctl is-active nginx |
active
|
sudo nginx -T | grep server_name |
daftar nama sesuai rencana, tidak ada duplikat |
โ ๏ธ Kesalahan umum & troubleshooting
| Gejala atau pesan | Artinya dan tindakan |
|---|---|
duplicate default server for 0.0.0.0:8080 |
ada dua default_server di port sama; hapus salah satu
|
conflicting server name "...", ignored |
nama ditulis di dua blok; yang pertama menang, sisanya mati |
open() ".../sites-enabled/x" failed (2: No such file) |
symlink menunjuk file yang sudah dihapus; buat ulang atau hapus symlink |
bind() to 0.0.0.0:80 failed (98: Address already in use) |
port dipakai Apache atau Nginx lain; cek dengan ss -lntp
|
directory index of "/srv/www/..." is forbidden |
tidak ada file index dan autoindex mati; benar, bukan bug
|
| 404 padahal file ada | root atau alias salah, sering karena garis miring penutup
|
413 Request Entity Too Large |
unggahan melebihi client_max_body_size bawaan 1 MB
|
could not build server_names_hash |
naikkan server_names_hash_bucket_size ke pangkat dua berikutnya
|
| reload sukses tapi situs tak berubah | file yang diedit tidak ter-include; buktikan dengan nginx -T
|
unexpected end of file, expecting "}" |
kurung kurawal tidak seimbang; cek blok yang terakhir diedit |
| 502 Bad Gateway | upstream mati atau alamatnya salah; ini lapis aplikasi, bukan lapis nama |
๐ Catatan keamanan & etika
- Jangan menaruh web root di dalam
/etc/nginx. Konfigurasi dan isi situs harus dipisah agar tidak ada file konfigurasi yang bisa diunduh. - Jangan
chmod 777folder web. Cukup755untuk folder dan644untuk file, dengan pemilikwww-data. - Jangan simpan
.git,.env,backup.zip, atau dump database di web root. Nginx menyajikan file apa adanya, tanpa bertanya apakah itu rahasia. - Matikan
autoindexkecuali untuk folder yang memang publik. Daftar file yang terbuka bisa membeberkan struktur internal. server_tokens off;menyembunyikan nomor versi Nginx dari header balasan. Kecil, tapi mempersulit pemindaian otomatis.- Perlakukan
nginx -Tsebagai dokumen internal: isinya path, nama host, dan alamat upstream. Jangan tempel mentah-mentah ke grup chat. - Uji konfigurasi di lab, bukan di server produksi. Satu
default_serverganda bisa membuat seluruh situs berhenti dimuat saat reload.
๐ Kesimpulan
Nginx memilih situs lewat tiga lapis: port, nama, lalu path. Virtual host hanyalah nama lain dari server block, dan default_server adalah milik port, bukan milik nama.
Kalau ada yang salah tampil, periksa berurutan: apakah port benar, apakah Host cocok dengan server_name, baru apakah location dan root menunjuk tempat yang tepat.
Langkah berikutnya: tambahkan HTTPS pada salah satu situs, lalu jadikan Nginx reverse proxy di depan aplikasi. Di situ lapis keempat muncul โ upstream โ dan cara berpikirnya tetap sama.
๐ Materi terkait
- Debian : Konfigurasi Web Server (Nginx) โ instalasi dan perintah dasar Nginx
- Debian : Konfigurasi Web Server (Apache) โ padanan konsep pada Apache
- Linux : Membuat Service Sendiri dengan systemd โ mengelola layanan seperti Nginx
- Linux : Log dan journalctl untuk Troubleshooting โ membaca log saat situs tidak muncul
- Linux : Firewall Dasar dengan nftables โ membuka port 80 dan 443 dengan aman
- Linux : Manajemen User, Group, dan sudo โ pemilik file dan izin web root
- Linux : Manajemen Paket dan Repositori Debian โ asal paket Nginx yang kamu pasang
๐ Referensi
- Nginx โ *How nginx processes a request*: https://nginx.org/en/docs/http/request_processing.html
- Nginx โ *Server names*: https://nginx.org/en/docs/http/server_names.html
- Nginx โ *Module ngx_http_core_module* (direktif
listen,location,root,alias,try_files): https://nginx.org/en/docs/http/ngx_http_core_module.html - Nginx โ *Module ngx_core_module* (
worker_processes,worker_connections): https://nginx.org/en/docs/ngx_core_module.html