Deploy Website Statis dan Node.js di VPS dengan Nginx (2026)
Menurut W3Techs, Nginx menjalankan sekitar sepertiga dari seluruh website yang web server-nya bisa diidentifikasi. Angka itu bukan kebetulan: Nginx ringan, stabil, dan bisa melayani banyak domain dari satu mesin. Bagi pelajar atau developer yang masih menghitung setiap rupiah, artinya sederhana. Satu server bisa menampung portofolio, landing page klien, dan API Node.js sekaligus, tanpa membuka langganan hosting baru untuk tiap proyek.
Masalahnya, banyak orang berhenti di tengah jalan. Situs jalan di localhost, tapi begitu dipindah ke server, muncul 502, proses mati, atau sertifikat HTTPS bermasalah. Artikel ini membedah empat masalah paling sering muncul beserta solusinya.
Masalah 1: Setiap Proyek Terasa Butuh Hosting Sendiri
Kebiasaan umum: satu proyek, satu paket hosting. Padahal website statis (HTML, CSS, JavaScript hasil build) hampir tidak membebani server. Nginx cukup membaca berkas dari disk dan mengirimkannya. Mengapa membayar lima layanan untuk lima situs yang masing-masing hanya dikunjungi puluhan orang per hari?
Solusinya adalah server block. Nginx memilih konfigurasi berdasarkan nama domain, sehingga satu VPS dapat melayani banyak situs. Jika Anda butuh tempat berlatih tanpa risiko, vps gratis untuk website adalah titik awal yang masuk akal sebelum memutuskan paket jangka panjang.
Mulai dari instalasi dan firewall dasar:
sudo apt update && sudo apt install -y nginx
# Izinkan SSH dan Nginx, lalu aktifkan firewall
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
Pastikan SSH diizinkan sebelum ufw enable. Kalau tidak, Anda mengunci diri sendiri dari server. Distribusi seperti vps ubuntu gratis cocok untuk panduan ini karena paket Nginx dan Certbot-nya tersedia langsung di repositori resmi.
Berikutnya, siapkan direktori dan server block untuk situs statis:
sudo mkdir -p /var/www/portofolio/current
sudo chown -R $USER:$USER /var/www/portofolio
sudo nano /etc/nginx/sites-available/portofolio
server {
listen 80;
server_name portofolio.contoh.com;
root /var/www/portofolio/current;
index index.html;
# Cache agresif untuk aset yang nama berkasnya ber-hash
location ~* \.(css|js|png|jpg|webp|svg|woff2)$ {
expires 30d;
add_header Cache-Control 'public, immutable';
}
location / {
# Fallback ke index.html agar cocok untuk SPA
try_files $uri $uri/ /index.html;
}
}
sudo ln -s /etc/nginx/sites-available/portofolio /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Selalu jalankan nginx -t sebelum reload. Perintah itu memeriksa sintaks, sehingga salah ketik tidak menjatuhkan semua situs Anda.
Masalah 2: Aplikasi Node.js Mati Saat Terminal Ditutup
Skenario klasik: Anda menjalankan node app.js lewat SSH, situs hidup, lalu koneksi terputus dan aplikasi ikut mati. Di rumah, itu sekadar mengganggu. Di produksi, itu berarti downtime.
Ada dua kesalahan yang sering terjadi bersamaan: membuka port aplikasi langsung ke internet, dan tidak memakai process manager. Analogi mudahnya, Nginx adalah resepsionis hotel dan aplikasi Node.js adalah tamu di kamar. Tamu tidak perlu berdiri di lobi menghadapi semua orang; resepsionis yang menyaring dan meneruskan.
Solusinya: systemd untuk menjaga proses, Nginx sebagai reverse proxy. Misalkan aplikasi Anda mendengarkan di port 3000 dan berada di /var/www/api/current. Buat unit service:
# /etc/systemd/system/api.service
[Unit]
Description=API Node.js
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/api/current
Environment=NODE_ENV=production
Environment=PORT=3000
ExecStart=/usr/bin/node server.js
# Hidupkan ulang otomatis bila crash
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now api
sudo systemctl status api
journalctl -u api -f # pantau log secara langsung
Lalu arahkan Nginx ke port tersebut:
server {
listen 80;
server_name api.contoh.com;
location / {
proxy_pass http://127.0.0.1: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;
# Dukungan WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
}
Jika Anda melihat 502 Bad Gateway, penyebab utamanya hampir selalu proses Node.js tidak berjalan atau port-nya tidak cocok. Cek systemctl status api dan pastikan aplikasi mengikat ke 127.0.0.1 pada port yang sama dengan proxy_pass.
Poin Penting: Jangan pernah mengekspos port aplikasi (misalnya 3000) ke publik. Biarkan hanya Nginx yang terbuka di port 80 dan 443, sedangkan aplikasi cukup mendengarkan di 127.0.0.1.
Masalah 3: Deploy Manual yang Rawan Salah dan Bikin Situs Down
Menyalin berkas lewat FTP atau menimpa folder langsung terdengar cepat, tetapi ada celah berbahaya. Selama proses salin berlangsung, pengunjung bisa mendapat halaman setengah jadi. Bila build gagal, versi lama sudah telanjur terhapus dan Anda tidak punya jalan kembali.
Solusinya: deploy berbasis rilis dengan symlink. Setiap versi masuk ke folder bertanggal, lalu symlink current dipindahkan dalam satu operasi atomik. Rollback tinggal mengarahkan symlink ke rilis sebelumnya.
#!/usr/bin/env bash
# deploy.sh - jalankan dari mesin lokal
set -euo pipefail
SERVER=deploy@IP_SERVER
APP_DIR=/var/www/portofolio
RELEASE=$(date +%Y%m%d%H%M%S)
# 1. Build lokal
npm ci && npm run build
# 2. Kirim hasil build ke folder rilis baru
rsync -az --delete dist/ $SERVER:$APP_DIR/releases/$RELEASE/
# 3. Alihkan symlink secara atomik, simpan 5 rilis terakhir
ssh $SERVER "ln -sfn $APP_DIR/releases/$RELEASE $APP_DIR/current && cd $APP_DIR/releases && ls -1t | tail -n +6 | xargs -r rm -rf"
Untuk aplikasi Node.js, tambahkan langkah npm ci --omit=dev di folder rilis, lalu jalankan sudo systemctl restart api setelah symlink berpindah. Buat pengguna khusus deploy dengan kunci SSH, bukan memakai root. Praktik ini sejalan dengan prinsip least privilege yang dianjurkan hampir semua panduan keamanan server.
Berikut perbandingan singkat dua pola yang kita bahas:
| Aspek | Website Statis | Aplikasi Node.js |
|---|---|---|
| Peran Nginx | Menyajikan berkas langsung | Reverse proxy ke port lokal |
| Proses tambahan | Tidak ada | systemd (atau process manager lain) |
| Beban server | Sangat rendah | Tergantung logika aplikasi |
| Rollback | Ganti symlink | Ganti symlink lalu restart service |
| Titik gagal umum | Salah path root | 502 karena proses mati atau port salah |
Masalah 4: Situs Masih HTTP dan Terbuka untuk Serangan Dasar
Browser modern menandai situs HTTP sebagai tidak aman, dan mesin pencari lebih menyukai HTTPS. Selain itu, server yang baru online biasanya langsung dipindai bot dalam hitungan menit. Itu bukan paranoia, cukup lihat /var/log/auth.log pada server baru dan Anda akan menemukan percobaan login dari alamat acak.
Solusinya: sertifikat gratis lewat Certbot plus pengerasan dasar. Pastikan DNS domain sudah mengarah ke IP server, lalu:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d portofolio.contoh.com -d api.contoh.com
# Uji pembaruan otomatis
sudo certbot renew --dry-run
Certbot mengedit konfigurasi Nginx, menambahkan pengalihan ke HTTPS, dan menjadwalkan perpanjangan otomatis. Tambahkan header keamanan di blok server:
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
server_tokens off;
Lengkapi dengan tiga kebiasaan: nonaktifkan login root lewat SSH, gunakan kunci SSH alih-alih kata sandi, dan pasang pembaruan keamanan otomatis lewat unattended-upgrades. Tiga langkah ini menutup sebagian besar celah yang dieksploitasi bot oportunistik.
Rencana Praktis untuk Akhir Pekan Ini
Kalau ingin langsung mencoba, urutannya begini:
- Siapkan server Ubuntu atau Debian, instal Nginx, dan aktifkan firewall.
- Deploy satu situs statis dengan server block dan struktur releases/current.
- Jalankan satu aplikasi Node.js sederhana lewat systemd, lalu proxy-kan dengan Nginx.
- Pasang HTTPS dengan Certbot dan uji pembaruan otomatisnya.
- Tulis skrip deploy supaya proses berikutnya cukup satu perintah.
Seluruh latihan ini bisa dikerjakan di server uji sebelum Anda membayar apa pun. Untuk melihat penawaran terkini dan memulai, kunjungi www.vpsgratis.id. Bila Anda mencari opsi dari sisi lokal, ketahui dulu apa yang ditawarkan vps gratis indonesia sebelum membandingkannya dengan free tier cloud global.
Terakhir, ukur hasilnya. Setelah semua berjalan, hitung berapa proyek yang kini hidup di satu server dan bandingkan dengan jumlah langganan hosting yang dulu Anda bayangkan. Selisih itulah efisiensi yang sesungguhnya, dan keterampilan Nginx, systemd, serta HTTPS yang Anda pelajari akan terpakai di hampir setiap pekerjaan DevOps ke depan.
