Zone file example.local yang kita buat di Bab 9 sudah menyimpan record www IN A 192.168.1.20, jadi nama domain itu sudah mengarah ke alamat yang benar. Masalahnya, DNS yang benar saja tidak otomatis berarti ada layanan yang berjalan di alamat tersebut. Buktikan sendiri dengan menjalankan perintah berikut dari komputer lain di jaringan yang sama.
curl http://192.168.1.20Hasilnya bukan halaman web, melainkan pesan:
curl: (7) Failed to connect to 192.168.1.20 port 80: Connection refusedDNS memang sudah benar, tapi belum ada satu pun proses yang mendengarkan di port 80 pada IP tersebut. Tugas kita selanjutnya adalah menyalakan software yang benar-benar menjawab permintaan HTTP di alamat itu, dan Nginx adalah jawabannya. Bab ini membuka Bagian IV series, bagian yang membahas layanan web secara khusus.
Kita akan mulai dari instalasi dan struktur direktori konfigurasi Nginx, lalu membuat virtual host (server block) untuk domain example.local yang sudah terdaftar di DNS. Setelah itu, kita mempraktikkan cara menyajikan static content dan dasar reverse proxy ke aplikasi backend, sebelum menutup bab dengan cara membaca access log dan error log untuk kebutuhan verifikasi maupun troubleshooting sehari-hari.
12.1 Instalasi dan Struktur Konfigurasi Nginx
Nginx (dibaca "engine-x") adalah web server sekaligus reverse proxy yang awalnya ditulis oleh Igor Sysoev untuk mengatasi C10K problem, yaitu tantangan melayani puluhan ribu koneksi bersamaan tanpa membebani resource server secara berlebihan. Berbeda dari Apache yang secara tradisional membuat satu proses atau thread untuk setiap koneksi, Nginx memakai arsitektur event-driven yang jauh lebih hemat memori saat menangani banyak koneksi sekaligus. Karakteristik inilah yang membuat Nginx jadi pilihan populer, baik sebagai web server murni maupun sebagai reverse proxy di depan aplikasi backend, topik yang akan kita perdalam lagi di Bab 16.
12.1.1 Instalasi Nginx dari Repository Ubuntu
Ubuntu Server menyediakan Nginx langsung di repository resmi, sehingga instalasinya tidak berbeda dari paket lain yang sudah kita pasang di bab-bab sebelumnya.
Langkah Praktik
- Perbarui daftar paket, lalu pasang Nginx.
Perintah ini sebenarnya memasangsudo apt update sudo apt install nginxnginxsebagai metapackage yang menarik salah satu varian, umumnyanginx-coreyang ringan dan cukup untuk kebutuhan web server standar. Varian lain sepertinginx-fullataunginx-extrasbaru relevan jika kita butuh module tambahan yang tidak ikut dalam build inti. - Berbeda dari
chronydi Bab 11 yang sudah terpasang sejak awal, paket Debian/Ubuntu untuk Nginx otomatis mengaktifkan dan menjalankan service-nya begitu instalasi selesai. Konfirmasi statusnya.systemctl status nginx.service - Buka akses port HTTP di UFW agar Visitor dari luar server bisa menjangkau Nginx.
sudo ufw allow 80/tcp - Uji dari komputer lain di jaringan yang sama, sekarang mengarah ke IP server tempat Nginx berjalan.
Jika berhasil, responsnya berupa halaman HTML sederhana berjudul "Welcome to nginx!", tanda Nginx sudah melayani request dengan konfigurasi bawaannya.curl http://192.168.1.20
Verifikasi dan Troubleshooting
- Periksa versi Nginx yang benar-benar terpasang, karena versi persis bisa berbeda tergantung kapan repository Ubuntu terakhir disinkronkan.
nginx -v - Jika
systemctl statusmenunjukkan service gagal start, penyebab paling umum adalah port 80 sudah dipakai proses lain. Periksa dengan:
Kasus ini sering terjadi kalau Apache (Bab 13) pernah dipasang lebih dulu di server yang sama. Kedua web server itu tidak bisa berjalan bersamaan di port yang sama tanpa konfigurasi khusus.sudo ss -tlnp | grep :80 - Jika curl dari komputer lain tetap gagal padahal service sudah
active (running), cek ulang rule UFW.sudo ufw status
12.1.2 Anatomi Direktori Konfigurasi Nginx
Sebelum membuat konfigurasi sendiri, penting memahami dulu bagaimana file-file konfigurasi Nginx saling terhubung. Salah paham soal struktur ini adalah salah satu sumber troubleshooting paling sering di lapangan, terutama saat perubahan yang sudah disimpan ternyata tidak pernah benar-benar dibaca oleh Nginx.
Langkah Praktik
- Lihat isi file konfigurasi utama.
Isinya kurang lebih seperti berikut, meski detail seperticat /etc/nginx/nginx.confworker_connectionsbisa sedikit berbeda tergantung versi paket yang terpasang.
Dua barisuser www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; } http { include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; }includeterakhir pada blokhttpadalah kunci untuk memahami struktur ini. Baris tersebut memberi tahu Nginx untuk membaca setiap file di/etc/nginx/conf.d/dan setiap file di/etc/nginx/sites-enabled/sebagai bagian dari konfigurasi aktif. - Lihat isi kedua direktori tersebut.
ls -la /etc/nginx/sites-available/ ls -la /etc/nginx/sites-enabled/
/etc/nginx/sites-available/ berisi semua file konfigurasi virtual host yang pernah kita buat, aktif maupun tidak, sedangkan /etc/nginx/sites-enabled/ hanya berisi symbolic link yang menunjuk balik ke file-file tertentu di sites-available. Konvensi dua direktori ini sebenarnya bukan fitur bawaan Nginx, melainkan konvensi packaging khas Debian dan Ubuntu untuk memudahkan kita mengaktifkan atau menonaktifkan sebuah site cukup dengan menambah atau menghapus symlink, tanpa perlu menghapus file konfigurasinya sama sekali. Server block bawaan bernama default sudah aktif sejak awal, itulah yang tadi menjawab curl kita dengan halaman "Welcome to nginx!", dan isinya disajikan dari /var/www/html.
Verifikasi dan Troubleshooting
- Setiap kali mengubah konfigurasi Nginx, biasakan menguji sintaksnya lebih dulu sebelum diterapkan. Kebiasaan ini akan terus kita pakai di seluruh bagian bab ini.
Output yang sehat menunjukkansudo nginx -tsyntax is okdantest is successful. Jika ada baris yang salah, pesan errornya biasanya sudah menyebutkan nama file dan nomor baris yang bermasalah, jadi tidak perlu menebak-nebak. - Di lapangan, kesalahan paling umum pemula adalah mengedit file di
sites-availabletapi lupa membuat symlink-nya disites-enabled, sehingga perubahan tidak pernah terbaca meskinginx -ttetap melaporkan sintaks valid.
12.2 Virtual Host (Server Block)
Di Nginx, satu blok konfigurasi yang mendefinisikan bagaimana sebuah domain dilayani disebut server block, istilah yang setara dengan virtual host di Apache (Bab 13). Server block memungkinkan satu server fisik atau satu IP address yang sama melayani banyak domain sekaligus, masing-masing dengan document root, konfigurasi, bahkan aplikasi backend yang berbeda. Mekanismenya mengandalkan header Host yang dikirim browser di setiap request HTTP, itulah cara Nginx tahu domain mana yang sedang diminta Visitor meski semuanya mengarah ke IP yang sama.
12.2.1 Membuat Server Block untuk example.local
Sekarang kita akan mengganti server block default bawaan dengan server block milik sendiri, yang benar-benar menyajikan halaman untuk domain example.local dan www.example.local sesuai record DNS yang sudah kita daftarkan di Bab 9.
Langkah Praktik
- Buat direktori document root khusus untuk domain ini, terpisah dari
/var/www/htmlmilik server block default.sudo mkdir -p /var/www/example.local/html - Buat halaman index sederhana untuk pengujian.
echo "<h1>Halaman example.local berjalan di Nginx</h1>" | sudo tee /var/www/example.local/html/index.html - Samakan kepemilikan direktori dengan user yang dipakai worker process Nginx, yaitu
www-data, sesuai barisuser www-data;yang sudah kita lihat dinginx.conf.sudo chown -R www-data:www-data /var/www/example.local - Buat file server block baru di
sites-available.sudo nano /etc/nginx/sites-available/example.local - Isi dengan konfigurasi berikut.
Directiveserver { listen 80; listen [::]:80; server_name example.local www.example.local; root /var/www/example.local/html; index index.html; location / { try_files $uri $uri/ =404; } }server_namemenentukan domain mana yang ditangani server block ini,rootmenunjuk document root-nya, dantry_filespada bloklocation /memerintahkan Nginx mencari file sesuai$uriyang diminta, mencoba sebagai direktori jika file tidak ditemukan, lalu mengembalikan404apabila keduanya tetap tidak ada. - Aktifkan server block ini dengan membuat symlink ke
sites-enabled.sudo ln -s /etc/nginx/sites-available/example.local /etc/nginx/sites-enabled/ - Nonaktifkan server block
defaultagar tidak lagi menjadi fallback yang membingungkan saat kita menambah domain lain nanti.
File aslinya disudo rm /etc/nginx/sites-enabled/defaultsites-available/defaulttetap dibiarkan ada sebagai referensi, hanya symlink aktifnya yang dihapus. - Uji sintaks, lalu terapkan perubahan.
Gunakansudo nginx -t sudo systemctl reload nginxreload, bukanrestart, untuk perubahan konfigurasi rutin seperti ini.reloadmembuat Nginx membaca ulang konfigurasi tanpa memutus koneksi yang sedang berlangsung, sedangkanrestartmematikan dulu seluruh proses sebelum menyalakannya kembali, yang berisiko menyebabkan jeda singkat pada layanan production. - Uji dari komputer lain di jaringan yang sama, kali ini lewat nama domain karena DNS internal dari Bab 9 sudah mengenalinya.
curl http://www.example.local
Verifikasi dan Troubleshooting
- Jika muncul error
[emerg] "server" directive is not allowed heresaatnginx -t, penyebab paling umum adalah kurung kurawal yang tidak seimbang di file konfigurasi. - Jika curl masih mengembalikan halaman "Welcome to nginx!" alih-alih halaman example.local, kemungkinan besar symlink ke
sites-enabled/defaultbelum benar-benar terhapus, atau reload belum dijalankan setelah perubahan. - Untuk client yang belum sempat menyinkronkan cache DNS-nya, uji langsung ke IP dengan header
Hostmanual agar tidak perlu menunggu propagasi.curl -H "Host: www.example.local" http://192.168.1.20
12.2.2 Multiple Virtual Host Berbasis Nama Domain
Kekuatan sebenarnya dari server block terlihat saat satu server melayani lebih dari satu domain. Skema ini disebut name-based virtual hosting, karena Nginx membedakan setiap domain murni berdasarkan header Host, bukan berdasarkan IP address atau nomor port yang berbeda-beda.
Langkah Praktik
- Siapkan document root untuk domain kedua, misalnya
blog.example.local.sudo mkdir -p /var/www/blog.example.local/html echo "<h1>Blog example.local</h1>" | sudo tee /var/www/blog.example.local/html/index.html sudo chown -R www-data:www-data /var/www/blog.example.local - Buat server block baru untuk domain ini.
sudo nano /etc/nginx/sites-available/blog.example.localserver { listen 80; listen [::]:80; server_name blog.example.local; root /var/www/blog.example.local/html; index index.html; location / { try_files $uri $uri/ =404; } } - Aktifkan, uji, dan terapkan seperti sebelumnya.
sudo ln -s /etc/nginx/sites-available/blog.example.local /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl reload nginx - Domain
blog.example.localbelum punya record di zone file Bab 9, jadi tambahkan dulu recordAbaru mengikuti pola yang sama dengan recordwwwyang sudah ada, lalu naikkan nomor Serial diSOAdan reload BIND9.
Untuk pengujian cepat tanpa menyentuh DNS server sama sekali, curl juga mendukung resolusi nama secara manual lewat flagblog IN A 192.168.1.20--resolve, cocok dipakai saat kita hanya ingin memverifikasi server block tanpa mengubah zone file lebih dulu.curl --resolve blog.example.local:80:192.168.1.20 http://blog.example.local/
Verifikasi dan Troubleshooting
- Bandingkan hasil
curl http://www.example.localdancurl http://blog.example.localdari IP server yang sama persis. Konten yang berbeda pada kedua domain itu membuktikan Nginx benar-benar memilih server block berdasarkan headerHost, bukan sekadar menyajikan satu konfigurasi yang sama untuk semua request. - Jika dua server block punya
server_nameyang sama secara tidak sengaja, Nginx tetap berjalan tanpa error saatnginx -t, tetapi hanya server block yang didefinisikan lebih dulu (berdasarkan urutan baca file) yang benar-benar dipakai. Hal ini adalah jebakan klasik yang sering luput dari perhatian karena tidak memunculkan pesan error apa pun.
12.3 Serving Static Content dan Reverse Proxy Dasar
Server block yang sudah kita buat sejauh ini menyajikan file statis apa adanya. Bagian ini memperdalam sedikit cara Nginx menyajikan static content, lalu masuk ke kemampuan yang membuat Nginx begitu populer di arsitektur modern: berperan sebagai reverse proxy di depan aplikasi backend.
12.3.1 Serving Static Content: root, alias, dan Halaman Error Kustom
Dua directive yang sering tertukar pemula adalah root dan alias. Directive root menempelkan path location di belakang path filesystem, sedangkan alias menggantikannya sepenuhnya. Salah pilih di antara keduanya adalah penyebab umum error 404 yang membingungkan meski file-nya sebenarnya ada di disk.
Langkah Praktik
- Buat halaman error kustom sederhana untuk status
404.echo "<h1>Halaman tidak ditemukan di example.local</h1>" | sudo tee /var/www/example.local/html/404.html - Tambahkan directive
error_pageke dalam server blockexample.local.sudo nano /etc/nginx/sites-available/example.local
Directiveerror_page 404 /404.html; location = /404.html { internal; }internalmemastikan halaman ini hanya bisa dicapai lewat mekanisme internal redirect milik Nginx sendiri, bukan diakses langsung oleh Visitor lewat URL/404.html. - Terapkan dan uji.
sudo nginx -t sudo systemctl reload nginx curl -i http://www.example.local/halaman-yang-tidak-ada
Verifikasi dan Troubleshooting
- Pada output
curl -i, perhatikan baris status pertama. Baris tersebut seharusnya tetap menunjukkanHTTP/1.1 404 Not Foundmeski isi halamannya sudah berupa halaman error kustom, bukan halaman404bawaan Nginx yang polos. - Di lapangan, kesalahan yang cukup sering muncul adalah menaruh directive
rootyang berbeda di dalam bloklocationtertentu, padahal maksudnya memakaialias. Kombinasiroot /var/www/example.local/html; location /assets { root /var/www/shared; }tetap menempelkan/assetsdi belakang pathroot-nya, sehingga file yang benar-benar dicari adalah/var/www/shared/assets/..., bukan/var/www/shared/...seperti yang sering diasumsikan.
12.3.2 Reverse Proxy ke Aplikasi Backend
Sebagai reverse proxy, Nginx menerima request dari Visitor lalu meneruskannya ke aplikasi backend yang berjalan di port lain, kemudian meneruskan kembali responsnya ke Visitor seolah-olah Nginx sendiri yang menjawab. Pola ini sangat umum dipakai Developer untuk aplikasi Node.js, Python, atau Java yang punya application server sendiri, tapi tidak dirancang untuk menghadapi traffic publik secara langsung. Bab 16 nanti akan memperluas topik ini sampai ke load balancing beberapa backend sekaligus, sedangkan di sini kita fokus dulu pada mekanisme dasarnya dengan satu backend saja.
Langkah Praktik
- Untuk menguji mekanisme reverse proxy tanpa perlu men-deploy aplikasi sungguhan, jalankan HTTP server sederhana bawaan Python sebagai backend tiruan yang hanya mendengarkan di
localhost.
Biarkan perintah ini berjalan di satu sesi terminal atau tmux (Bab 3) tersendiri, karena prosesnya berjalan di foreground.mkdir -p ~/demo-backend && cd ~/demo-backend echo "Halo dari backend port 8080" > index.html python3 -m http.server 8080 --bind 127.0.0.1 - Di terminal lain, tambahkan blok
locationbaru pada server blockexample.localyang meneruskan request ke backend tersebut.sudo nano /etc/nginx/sites-available/example.locallocation /app/ { proxy_pass http://127.0.0.1:8080/; 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; } - Terapkan dan uji.
Responsnya seharusnya menampilkan isisudo nginx -t sudo systemctl reload nginx curl http://www.example.local/app/index.htmldari backend Python tadi, padahal Visitor hanya berkomunikasi dengan Nginx di port 80.
Tiga directive proxy_set_header di atas bukan sekadar formalitas. Tanpa Host, backend menerima Host: 127.0.0.1 alih-alih nama domain asli yang diminta Visitor, yang bisa merusak aplikasi yang membangun URL absolut berdasarkan header ini. Tanpa X-Real-IP dan X-Forwarded-For, log aplikasi backend hanya akan mencatat IP Nginx itu sendiri (127.0.0.1) sebagai sumber semua request, bukan IP Visitor yang sebenarnya, yaitu masalah yang baru terasa saat Sysadmin butuh menelusuri sumber traffic mencurigakan atau serangan brute-force di backend.
Verifikasi dan Troubleshooting
- Error
502 Bad Gatewayhampir selalu berarti Nginx tidak bisa menghubungi backend diproxy_pass. Pastikan proses backend-nya masih berjalan.ss -tlnp | grep 8080 - Perhatikan tanda garis miring (
/) di akhir path padalocation /app/danproxy_pass http://127.0.0.1:8080/. Kombinasi garis miring di kedua sisi ini membuat Nginx menghapus prefix/app/sebelum meneruskan request ke backend. Jika salah satu garis miring dihilangkan, prefix tersebut justru ikut terbawa ke backend, dan hasilnya sering berupa404yang membingungkan karena terlihat benar di konfigurasi tapi salah pada praktiknya.
12.4 Log Access dan Error
Dua file log adalah sumber informasi utama saat kita perlu memverifikasi traffic atau menelusuri masalah pada Nginx, jauh lebih cepat dibanding menebak-nebak dari gejala di sisi client.
12.4.1 Membaca Access Log dan Error Log
Access log mencatat setiap request yang berhasil diterima Nginx, sedangkan error log mencatat kejadian di luar kondisi normal, mulai dari warning ringan sampai kegagalan proxy ke backend. Secara default, keduanya tersimpan di /var/log/nginx/access.log dan /var/log/nginx/error.log, sesuai directive access_log dan error_log yang sudah kita lihat di nginx.conf pada Bagian 12.1.2.
Langkah Praktik
- Pantau access log secara real-time di satu sesi terminal.
sudo tail -f /var/log/nginx/access.log - Dari terminal lain, kirim beberapa request ke server, lalu perhatikan baris baru yang muncul di access log.
Setiap baris log kurang lebih berformat seperti berikut, mengikuti log formatcurl http://www.example.local curl http://www.example.local/halaman-yang-tidak-adacombinedyang jadi standar de facto banyak web server.
Urutan field-nya adalah IP client, identitas remote user (biasanya192.168.1.5 - - [26/Aug/2026:10:15:03 +0700] "GET / HTTP/1.1" 200 512 "-" "curl/8.5.0"-karena jarang dipakai), timestamp, baris request lengkap, HTTP status code, ukuran response dalam byte, referer, dan terakhir user agent. - Tekan
Ctrl+Cuntuk menghentikantail -f, lalu lihat error log untuk membandingkan.sudo tail -n 20 /var/log/nginx/error.log
Verifikasi dan Troubleshooting
- Kolom status code di access log adalah titik awal paling cepat untuk menilai kesehatan traffic secara kasar. Rentetan
5xxyang tiba-tiba muncul biasanya menandakan masalah di sisi server atau backend, sedangkan lonjakan4xx, terutama404, sering menandakan link rusak atau Attacker yang sedang melakukan scanning path-path umum secara serampangan. - Jika ingin memisahkan log per domain agar lebih mudah dianalisis, tambahkan directive
access_logdanerror_logsendiri di dalam server block tertentu, menimpa pengaturan global dinginx.conf.access_log /var/log/nginx/example.local.access.log; error_log /var/log/nginx/example.local.error.log;
12.4.2 Level Error Log dan Rotasi Log
Directive error_log menerima parameter level opsional yang mengatur seberapa detail pesan yang dicatat, berurutan dari yang paling ringan ke paling kritis: debug, info, notice, warn, error, crit, alert, dan emerg. Level bawaan adalah error, cukup untuk operasional harian, tapi terlalu minim saat kita sedang menelusuri bug yang sulit direproduksi.
Langkah Praktik
- Naikkan sementara level error log ke
debugsaat butuh detail maksimal untuk troubleshooting, misalnya pada server blockexample.localyang sedang bermasalah.
Levelerror_log /var/log/nginx/example.local.error.log debug;debughanya berfungsi jika binary Nginx dikompilasi dengan opsi--with-debug. Cek dulu dengannginx -Vsebelum mengandalkan level ini, dan jangan lupa mengembalikannya kewarnatauerrorsetelah selesai, karena leveldebugmenghasilkan volume log yang sangat besar dan cepat memenuhi disk pada server production. - Pastikan rotasi log sudah berjalan otomatis, karena tanpa rotasi,
access.logdanerror.logakan terus membesar tanpa batas.cat /etc/logrotate.d/nginx
Verifikasi dan Troubleshooting
- Paket
nginxdari repository Ubuntu sudah menyertakan konfigurasilogrotateini secara default, umumnya berjalan harian dan menyimpan beberapa hari riwayat sebelum file lama dihapus atau dikompresi. Pembahasan lebih dalam soal strategi retensi log lintas server akan kita bahas di Bab 39. - Jika disk server tiba-tiba penuh dan dugaan mengarah ke log Nginx, periksa dulu ukurannya sebelum menyalahkan volume traffic.
sudo du -sh /var/log/nginx/*
Sampai di sini, Nginx sudah berjalan sebagai web server yang benar-benar menjawab domain example.local dan blog.example.local, lengkap dengan static content, reverse proxy dasar ke backend, serta access log dan error log yang siap kita baca kapan pun dibutuhkan. Bab 13 akan membahas Apache sebagai alternatif web server yang masih banyak dipakai di berbagai infrastruktur, sekaligus membandingkannya dengan Nginx supaya kita punya dasar yang jelas untuk memilih salah satunya sesuai kebutuhan.

