Kalau sebuah web gak bisa dibuka, masalahnya bisa ada di banyak tempat: namanya gak ketemu, server-nya gak bisa dihubungi, atau app di dalam server-nya mati. Network tools di terminal mengecek tempat-tempat itu satu per satu. Bayangin kamu mau mengantar paket ke kantor teman. Pertama kamu cari alamatnya (dig), lalu cek gedungnya bisa didatangi (ping), lalu tanya resepsionis di lobi (curl -I), dan terakhir cek temanmu ada di mejanya (ss). Begitu satu langkah gagal, kamu tahu masalahnya di mana.
🧪 Tebakan cepat: app Node di server mati, tapi server-nya sendiri nyala.
ping belajarweb.devhasilnya sukses atau gagal? Tebak dulu, jawabannya ada di bagian "ping: server-nya bisa dihubungi?".
dig: nama domain jadi alamat IP
Komputer menghubungi server lewat alamat IP, jadi langkah pertama selalu mengubah nama jadi IP lewat DNS. dig menanyakan itu dan mencetak jawabannya:
$ dig belajarweb.dev
; <<>> DiG 9.18.28 <<>> belajarweb.dev
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41872
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;belajarweb.dev. IN A
;; ANSWER SECTION:
belajarweb.dev. 300 IN A 203.0.113.10
;; Query time: 24 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Thu Oct 08 14:37:02 WIB 2026
;; MSG SIZE rcvd: 59
status: NOERRORartinya pertanyaannya terjawab. Kalau namanya gak terdaftar, isinyaNXDOMAINdanANSWER: 0.- Baris di ANSWER SECTION adalah jawabannya: nama, TTL (berapa detik jawaban ini boleh disimpan di cache, di sini 300),
IN A(record IPv4), lalu IP-nya,203.0.113.10. dig belajarweb.dev +shortcuma mencetak IP-nya:203.0.113.10.
ping: server-nya bisa dihubungi?
ping mengirim paket kecil ke sebuah mesin dan mengukur berapa lama balasannya datang:
$ ping -c 3 belajarweb.dev
PING belajarweb.dev (203.0.113.10) 56(84) bytes of data.
64 bytes from 203.0.113.10: icmp_seq=1 ttl=54 time=12.4 ms
64 bytes from 203.0.113.10: icmp_seq=2 ttl=54 time=11.9 ms
64 bytes from 203.0.113.10: icmp_seq=3 ttl=54 time=12.1 ms
--- belajarweb.dev ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 11.900/12.133/12.400/0.205 ms
-c 3berhenti setelah 3 paket. Tanpa-c, ping di Linux jalan terus sampai kamu tekan Ctrl+C.time=12.4 msadalah waktu bolak-balik satu paket.0% packet lossartinya semua paket dibalas.
ping cuma mengecek mesinnya, bukan app di dalamnya. Selama server-nya nyala, ping tetap sukses walau app Node-nya mati. Itu jawaban tebakannya. Sebaliknya, ada server yang sengaja menolak ping, jadi ping gagal belum tentu web-nya mati.
curl -I: web-nya menjawab apa?
curl -I mengirim request HEAD: minta header response saja, tanpa body. Cocok untuk melihat status code dengan cepat:
$ curl -I https://belajarweb.dev
HTTP/2 200
server: nginx/1.24.0 (Ubuntu)
date: Thu, 08 Oct 2026 07:37:02 GMT
content-type: text/html; charset=utf-8
content-length: 5120
cache-control: public, max-age=600
Kalau app Node di belakang nginx mati, nginx tetap menjawab, tapi dengan HTTP/2 502 (Bad Gateway): "aku hidup, tapi app di belakangku gak bisa dihubungi". Kalau namanya gak ada di DNS, curl berhenti sebelum mengirim apa pun: curl: (6) Could not resolve host: api.belajarweb.dev.
curl -v menampilkan semuanya: baris yang diawali > adalah request yang dikirim, baris < adalah response dari server. Output -v ditulis ke stderr, jadi untuk menyaringnya dengan grep kamu harus menggabungkannya dulu dengan 2>&1:
curl -v https://belajarweb.dev 2>&1 | grep "< HTTP"
# < HTTP/2 200
ss dan netstat: siapa yang listen di port mana?
Di server, app yang siap menerima koneksi disebut listen di sebuah port. ss -tlnp (TCP, listening, angka, process) menampilkan semuanya:
$ sudo ss -tlnp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=701,fd=3))
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=812,fd=6))
LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=812,fd=7))
LISTEN 0 511 127.0.0.1:3000 0.0.0.0:* users:(("node",pid=4821,fd=21))
LISTEN 0 244 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=903,fd=6))
0.0.0.0:443artinya nginx menerima koneksi dari mana saja.127.0.0.1:3000artinya Node cuma menerima koneksi dari server itu sendiri, makanya pengunjung lewat nginx dulu.- Kalau app Node mati, baris
127.0.0.1:3000hilang dari daftar. lsof -i :3000menjawab pertanyaan yang sama dari arah port: proses mana yang memakai port 3000.
$ sudo lsof -i :3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 4821 deploy 21u IPv4 38212 0t0 TCP localhost:3000 (LISTEN)
netstat adalah pendahulu ss yang masih sering ketemu. netstat -tan mencetak kolom Proto, Recv-Q, Send-Q, Local Address, Foreign Address, dan State. Kolom State yang paling sering muncul: LISTEN (menunggu koneksi), ESTABLISHED (koneksi sedang terhubung), dan TIME_WAIT (koneksi baru ditutup, sebentar lagi dibuang).
Di latihan: membaca output netstat dengan JavaScript
Latihannya memakai netstat versi ringkas: kolom Recv-Q dan Send-Q dibuang, jadi tiap baris tinggal empat kolom: proto, alamat lokal, alamat tujuan, state. Ini output yang dibaca:
| Baris | proto | local | foreign | state |
|---|---|---|---|---|
| 1 | tcp | 127.0.0.1:3000 | 0.0.0.0:* | LISTEN |
| 2 | tcp | 192.168.1.5:52341 | 93.184.216.34:443 | ESTABLISHED |
| 3 | tcp | 127.0.0.1:5432 | 0.0.0.0:* | LISTEN |
| 4 | tcp | 192.168.1.5:52342 | 8.8.8.8:53 | TIME_WAIT |
const line = "tcp 127.0.0.1:3000 0.0.0.0:* LISTEN";
const [proto, local, foreign, state] = line.trim().split(/\s+/);
console.log(local); // 127.0.0.1:3000
console.log("listen".toLowerCase() === state.toLowerCase()); // true
split(/\s+/)memecah di satu atau lebih spasi.split(" ")akan menghasilkan teks kosong di antara dua spasi.- Output aslinya dipecah dulu per baris dengan
split("\n"), dan baris kosong dibuang sebelum dipetakan. - Menyamakan huruf dengan
toLowerCase()di kedua sisi bikin"established"cocok denganESTABLISHED. Dari empat baris di atas ada 2 LISTEN dan 1 ESTABLISHED. Kalau gak ada yang cocok, hasilnya array kosong, panjangnya 0.
⚠️ Jebakan yang sering ketemu
- Mengira ping sukses berarti web-nya sehat. Ping cuma membuktikan mesinnya hidup. Cek web-nya dengan
curl -I, dan app-nya denganss -tlnp. - Lupa
2>&1saat menyaringcurl -v. Detail-vada di stderr, jadicurl -v url | grep "< HTTP"gak menemukan apa-apa. - Bingung 127.0.0.1 dan 0.0.0.0. App yang listen di
127.0.0.1gak bisa dibuka dari luar server, walau port-nya benar. - Memecah baris per satu spasi. Di output terminal, jarak antar kolom bisa beberapa spasi. Pakai
/\s+/, buang baris kosong, dan bandingkan state tanpa peduli huruf besar kecil.
TL;DR: Saat web gak bisa dibuka, cek berurutan. dig nama (atau +short): namanya jadi IP? NXDOMAIN artinya record-nya gak ada. ping -c 3 nama: mesinnya bisa dihubungi? Tapi ping cuma mengecek mesin, bukan app. curl -I url: header saja, tanpa body; 200 sehat, 502 artinya nginx hidup tapi app di belakangnya mati. curl -v url 2>&1 | grep "< HTTP" menyaring baris status response. Di server, ss -tlnp (atau netstat) menampilkan siapa yang LISTEN di port mana, dan lsof -i :3000 menunjukkan proses yang memakai port 3000. State yang penting: LISTEN, ESTABLISHED, TIME_WAIT.