1. Perbandingan Provider VPS
Ketika aplikasi IoT kamu sudah siap di production, langkah selanjutnya adalah deploy ke VPS (Virtual Private Server). VPS memberikan kamu server virtual dengan akses root penuh, berbeda dari shared hosting yang terbatas.
Memilih provider VPS yang tepat sangat penting. Berikut perbandingan provider populer untuk developer IoT:
| Provider | Harga Mulai | Lokasi Server | Kelebihan | Kekurangan |
|---|---|---|---|---|
| DigitalOcean | $4/bulan | SGP, US, EU | Dokumentasi lengkap, UI intuitif, Marketplace apps | Harga lebih mahal untuk spesifikasi sama |
| Vultr | $2.50/bulan | SGP, JP, US, EU | Harga bersaing, banyak lokasi Asia, performa bagus | Support kurang responsif |
| Hetzner | €3.29/bulan | EU, US | Harga paling murah, spesifikasi tinggi | Tidak ada server Asia (latency tinggi ke Indonesia) |
| Linode (Akamai) | $5/bulan | SGP, JP, US, EU | Stabil, performa konsisten, StackScript | Fitur kurang inovatif |
| UpCloud | €7/bulan | SGP, US, EU | MaxIOPS storage sangat cepat, uptime tinggi | Harga lebih mahal, kurang populer |
| Google Cloud (f1-micro) | Gratis tier | Global | Gratis 1 instance f1-micro, integrasi GCP lengkap | Konfigurasi kompleks, biaya tak terduga jika salah setup |
Untuk latency terbaik ke Indonesia, pilih server di Singapura (SGP). DigitalOcean, Vultr, dan Linode punya data center di SGP. Jika budget terbatas dan latency tidak kritis, Hetzner di EU menawarkan spesifikasi paling tinggi dengan harga paling murah.
Spesifikasi yang Direkomendasikan
Untuk aplikasi IoT skala kecil-menengah (100-1000 device), spesifikasi berikut sudah cukup:
- CPU: 1-2 vCPU (cukup untuk Node.js single-threaded)
- RAM: 1-2 GB (Node.js + Nginx + monitoring)
- Storage: 25-50 GB SSD (database + log + backup)
- Bandwidth: 1-2 TB/bulan (data sensor ringan)
- OS: Ubuntu 22.04 LTS atau 24.04 LTS
2. Server Setup Awal
Setelah membuat VPS baru, ada beberapa langkah penting yang harus dilakukan sebelum menginstall aplikasi apapun. Langkah-langkah ini memastikan server kamu aman dan siap digunakan.
Langkah 1: Login via SSH
# Login dengan IP VPS kamu
ssh root@YOUR_VPS_IP
# Contoh:
ssh root@203.0.113.50
# Jika menggunakan SSH key (lebih aman):
ssh -i ~/.ssh/id_rsa root@203.0.113.50
Langkah 2: Update Sistem
# Update package list
sudo apt update
# Upgrade semua package ke versi terbaru
sudo apt upgrade -y
# Install tools yang sering dibutuhkan
sudo apt install -y curl wget git htop unzip software-properties-common ufw
# Reboot jika kernel diupgrade
sudo reboot
Langkah 3: Konfigurasi Timezone
# Set timezone ke Waktu Indonesia Barat (WIB)
sudo timedatectl set-timezone Asia/Jakarta
# Verifikasi
timedatectl
# Output: Time zone: Asia/Jakarta (WIB, +0700)
Langkah 4: Buat User Baru
# Buat user baru (jangan gunakan root untuk operasi sehari-hari)
sudo adduser iotdev
# Masukkan password yang kuat, sisanya tekan Enter
# Tambahkan ke grup sudo agar bisa menjalankan perintah admin
sudo usermod -aG sudo iotdev
# Test login dengan user baru
su - iotdev
sudo whoami
# Output: root
Langkah 5: Setup Firewall (UFW)
# Default policy: tolak semua incoming, izinkan semua outgoing
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Izinkan port yang dibutuhkan
sudo ufw allow ssh # Port 22 untuk SSH
sudo ufw allow 80/tcp # Port 80 untuk HTTP
sudo ufw allow 443/tcp # Port 443 untuk HTTPS
# Aktifkan firewall
sudo ufw enable
# Ketik 'y' saat dikonfirmasi
# Cek status
sudo ufw status verbose
# Status: active
# 22/tcp ALLOW IN Anywhere
# 80/tcp ALLOW IN Anywhere
# 443/tcp ALLOW IN Anywhere
Pastikan SSH (port 22) diizinkan sebelum mengaktifkan UFW. Jika tidak, kamu akan terkunci dari server! Jika menggunakan port SSH custom (misal 2222), ganti allow ssh dengan allow 2222/tcp.
3. SSH Hardening
SSH adalah pintu utama ke server kamu. Jika SSH tidak diamankan, server kamu rentan terhadap brute force attack. Berikut beberapa langkah untuk mengamankan SSH:
Generate SSH Key Pair
# Generate SSH key pair di komputer lokal (bukan di server!)
# ED25519 lebih aman dan cepat dari RSA
ssh-keygen -t ed25519 -C "iotdev@beebane.com"
# Tekan Enter untuk default path, masukkan passphrase jika mau
# Copy public key ke server
ssh-copy-id iotdev@YOUR_VPS_IP
# Test login tanpa password
ssh iotdev@YOUR_VPS_IP
Konfigurasi sshd_config
# Backup config asli (SELALU backup sebelum edit!)
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
# Edit konfigurasi SSH
sudo nano /etc/ssh/sshd_config
# Ubah atau tambahkan baris berikut:
PermitRootLogin no # Nonaktifkan login root
PasswordAuthentication no # Nonaktifkan password, hanya SSH key
PubkeyAuthentication yes # Aktifkan SSH key authentication
Port 2222 # Ganti port default (opsional tapi disarankan)
MaxAuthTries 3 # Batasi percobaan login gagal
ClientAliveInterval 300 # Timeout idle 5 menit
ClientAliveCountMax 2 # Disconnect setelah 2x timeout
# Test konfigurasi (jangan restart dulu!)
sudo sshd -t
# Tidak ada output = config benar
# Restart SSH service
sudo systemctl restart sshd
Install Fail2Ban
# Install Fail2Ban (auto-ban IP yang gagal login berulang kali)
sudo apt install -y fail2ban
# Buat konfigurasi custom (jangan edit file asli)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit konfigurasi
sudo nano /etc/fail2ban/jail.local
# Pastikan bagian [sshd] aktif:
# [sshd]
# enabled = true
# port = 2222 (sesuaikan dengan port SSH kamu)
# bantime = 3600 (ban IP selama 1 jam)
# findtime = 600 (dalam periode 10 menit)
# maxretry = 3 (setelah 3x percobaan gagal)
# Aktifkan dan jalankan
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Cek status
sudo fail2ban-client status sshd
Sebelum menonaktifkan PasswordAuthentication, pastikan SSH key sudah berhasil digunakan untuk login. Buka terminal baru dan test login dengan SSH key sebelum menutup sesi SSH root yang lama. Jika SSH key gagal, kamu masih punya akses root untuk memperbaiki.
4. Nginx Setup
Nginx akan berfungsi sebagai reverse proxy di depan aplikasi Node.js kamu. Nginx menangani SSL, caching, compression, dan meneruskan request ke aplikasi.
Instalasi Nginx
# Instalasi Nginx
sudo apt install -y nginx
# Aktifkan saat boot dan jalankan
sudo systemctl enable nginx
sudo systemctl start nginx
# Cek status
sudo systemctl status nginx
# Buka port HTTP dan HTTPS di firewall
sudo ufw allow 'Nginx Full'
Konfigurasi Reverse Proxy untuk Node.js
server {
listen 80;
server_name iotkamu.com www.iotkamu.com;
# Redirect semua HTTP ke HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name iotkamu.com www.iotkamu.com;
# SSL akan dikonfigurasi nanti oleh Certbot
# ssl_certificate /etc/letsencrypt/live/iotkamu.com/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/iotkamu.com/privkey.pem;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Strict-Transport-Security "max-age=31536000" always;
# Gzip compression untuk response yang lebih kecil
gzip on;
gzip_types text/plain application/json application/javascript text/css;
# Reverse proxy ke Node.js app di port 3000
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_read_timeout 90;
}
# Static files (jika ada)
location /public/ {
alias /var/www/iot-app/public/;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
# Aktifkan site
sudo ln -s /etc/nginx/sites-available/iot-app /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
# Test konfigurasi
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
5. Domain & SSL
Menggunakan domain lebih profesional daripada IP address. Dan SSL (HTTPS) wajib untuk keamanan data IoT yang dikirim dari device ke server.
Setup DNS Record
Di registrar domain kamu (Namecheap, Cloudflare, Niagahoster, dll), tambahkan DNS record berikut:
| Type | Name | Value | TTL |
|---|---|---|---|
| A | @ | YOUR_VPS_IP | 300 |
| A | www | YOUR_VPS_IP | 300 |
| A | api | YOUR_VPS_IP | 300 |
# Cek apakah DNS sudah mengarah ke VPS
nslookup iotkamu.com
# Address: 203.0.113.50
# Atau gunakan dig
dig iotkamu.com +short
# Output: 203.0.113.50
Install SSL dengan Let's Encrypt
# Install Certbot dan plugin Nginx
sudo apt install -y certbot python3-certbot-nginx
# Dapatkan SSL certificate (otomatis update Nginx config)
sudo certbot --nginx -d iotkamu.com -d www.iotkamu.com
# Ikuti wizard:
# 1. Masukkan email untuk notifikasi renewal
# 2. Agree to Terms of Service (Y)
# 3. Share email dengan EFF (N - optional)
# 4. Redirect HTTP to HTTPS (2 - pilih yang ini)
# Test auto-renewal (pastikan cron job berjalan)
sudo certbot renew --dry-run
6. Deploy Aplikasi Node.js
Sekarang kita deploy aplikasi Node.js IoT ke server. Kita akan menggunakan Git untuk transfer code dan PM2 untuk menjalankan aplikasi.
Install Node.js
# Install NVM (Node Version Manager) - cara terbaik manage Node.js
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
# Install Node.js LTS (Long Term Support)
nvm install --lts
nvm use --lts
# Verifikasi instalasi
node -v # v20.x.x
npm -v # 10.x.x
Clone & Setup Aplikasi
# Buat direktori untuk aplikasi
sudo mkdir -p /var/www/iot-app
sudo chown $USER:$USER /var/www/iot-app
# Clone repository dari GitHub
cd /var/www/iot-app
git clone https://github.com/kamu/iot-api.git .
# Install dependencies (hanya production, tanpa devDependencies)
npm install --production
# Buat file environment variables
nano .env
# Isi dengan variabel environment:
NODE_ENV=production
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_USER=iot_user
DB_PASS=password_kuat
DB_NAME=iot_db
JWT_SECRET=random_secret_key_minimal_32_karakter
# Test jalankan aplikasi
node app.js
# Output: Server berjalan di port 3000
Menjalankan node app.js secara langsung hanya untuk testing. Di production, gunakan PM2 sebagai process manager (dijelaskan di section berikutnya). PM2 memastikan aplikasi tetap berjalan, restart otomatis saat crash, dan mengelola log.
7. PM2 Process Manager
PM2 adalah process manager untuk Node.js yang paling populer di production. PM2 memastikan aplikasi tetap berjalan 24/7, restart otomatis saat crash, menjalankan multiple instances (cluster mode), dan mengelola log.
Instalasi & Konfigurasi PM2
# Install PM2 secara global
npm install -g pm2
# Jalankan aplikasi dengan PM2
cd /var/www/iot-app
pm2 start app.js --name iot-api
# Cek status (akan muncul tabel dengan PID, status, CPU, memory)
pm2 status
# Lihat log real-time
pm2 logs iot-api
# Setup PM2 agar otomatis start saat server reboot
pm2 startup systemd
# Jalankan perintah yang diberikan oleh output di atas
# Simpan daftar proses PM2
pm2 save
Ecosystem Configuration
module.exports = {
apps: [{
name: "iot-api",
script: "./app.js",
instances: "max", // Gunakan semua CPU core
exec_mode: "cluster", // Cluster mode untuk performa
env: {
NODE_ENV: "development",
PORT: 3000
},
env_production: {
NODE_ENV: "production",
PORT: 3000
},
max_memory_restart: "500M", // Restart jika memory > 500MB
log_date_format: "YYYY-MM-DD HH:mm:ss",
error_file: "./logs/err.log",
out_file: "./logs/out.log",
merge_logs: true,
watch: false, // Jangan watch di production
max_restarts: 10, // Maksimal 10x restart
restart_delay: 5000 // Delay 5 detik antar restart
}]
};
PM2 Commands Lengkap
| Perintah | Fungsi |
|---|---|
pm2 start app.js --name nama | Menjalankan aplikasi |
pm2 stop nama | Menghentikan aplikasi |
pm2 restart nama | Restart aplikasi |
pm2 reload nama | Graceful restart (zero downtime) |
pm2 delete nama | Menghapus dari daftar PM2 |
pm2 status | Menampilkan status semua proses |
pm2 logs nama | Menampilkan log real-time |
pm2 monit | Monitoring CPU & memory |
pm2 update | Update PM2 tanpa restart |
Deploy dengan Git Pull
# Script deploy sederhana - simpan sebagai deploy.sh
#!/bin/bash
set -e
echo "🚀 Mulai deploy..."
cd /var/www/iot-app
echo "📥 Pull kode terbaru..."
git pull origin main
echo "📦 Install dependencies..."
npm install --production
echo "🔄 Reload aplikasi..."
pm2 reload iot-api
echo "✅ Deploy berhasil! $(date)"
8. Monitoring Server
Setelah deploy, kamu perlu memantau kesehatan server secara berkala. Monitoring yang baik bisa mendeteksi masalah sebelum menjadi kritis.
Monitoring Dasar dengan Command Line
# CPU, Memory, Process - tampilan interaktif
htop
# Disk usage
df -h
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 50G 12G 38G 24% /
# Memory usage
free -h
# total used free shared buff/cache available
# Mem: 2.0Gi 800Mi 600Mi 10Mi 600Mi 1.1Gi
# Cek port yang terbuka dan prosesnya
ss -tlnp
# State Recv-Q Send-Q Local Address:Port Process
# LISTEN 0 128 0.0.0.0:80 nginx
# LISTEN 0 128 0.0.0.0:443 nginx
# LISTEN 0 511 127.0.0.1:3000 node
Monitoring Otomatis dengan Script
#!/bin/bash
# monitor.sh - Script monitoring server IoT
LOG_FILE="/var/log/server-monitor.log"
DATE=$(date "+%Y-%m-%d %H:%M:%S")
# Cek CPU usage
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')
# Cek Memory usage
MEM_USAGE=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100}')
# Cek Disk usage
DISK_USAGE=$(df / | grep / | awk '{print $5}' | sed 's/%//')
# Cek Node.js app status via PM2
APP_STATUS=$(pm2 jlist 2>/dev/null | python3 -c \
"import sys,json; d=json.load(sys.stdin); print(d[0]['pm2_env']['status'])" \
2>/dev/null || echo "offline")
# Log hasil
echo "$DATE | CPU: ${CPU_USAGE}% | MEM: ${MEM_USAGE}% | DISK: ${DISK_USAGE}% | APP: $APP_STATUS" >> $LOG_FILE
# Alert jika CPU > 90% atau disk > 85%
if (( $(echo "$CPU_USAGE > 90" | bc -l) )); then
echo "⚠️ CPU tinggi: ${CPU_USAGE}%" | mail -s "Server Alert" admin@iotkamu.com
fi
if [ "$DISK_USAGE" -gt 85 ]; then
echo "⚠️ Disk penuh: ${DISK_USAGE}%" | mail -s "Server Alert" admin@iotkamu.com
fi
# Buat script executable
chmod +x /var/www/iot-app/monitor.sh
# Tambahkan cron job (setiap 5 menit)
crontab -e
# Tambahkan baris berikut:
*/5 * * * * /var/www/iot-app/monitor.sh
9. Backup Strategy
Backup adalah asuransi untuk data IoT kamu. Tanpa backup, satu kesalahan (hapus file, disk corrupt, serangan ransomware) bisa menghilangkan semua data sensor yang sudah dikumpulkan selama berbulan-bulan.
Strategi 3-2-1 Backup
- 3 salinan data (1 primary + 2 backup)
- 2 jenis media berbeda (SSD server + cloud storage)
- 1 backup offsite (di lokasi berbeda / cloud)
Script Backup Otomatis
#!/bin/bash
# backup.sh - Backup otomatis aplikasi IoT
BACKUP_DIR="/var/backups/iot"
APP_DIR="/var/www/iot-app"
DB_NAME="iot_db"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=30
# Buat direktori backup
mkdir -p $BACKUP_DIR
# 1. Backup kode aplikasi
tar -czf $BACKUP_DIR/app_$DATE.tar.gz -C $APP_DIR .
# 2. Backup database (contoh PostgreSQL)
pg_dump -U iot_user $DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# 3. Backup konfigurasi Nginx
tar -czf $BACKUP_DIR/nginx_$DATE.tar.gz /etc/nginx/
# 4. Backup file environment (.env)
cp $APP_DIR/.env $BACKUP_DIR/env_$DATE.bak
# 5. Hapus backup yang lebih lama dari 30 hari
find $BACKUP_DIR -type f -mtime +$RETENTION_DAYS -delete
# 6. Upload ke cloud storage (opsional, pakai rclone)
# rclone copy $BACKUP_DIR remote:iot-backup/ --include "*$DATE*"
echo "✅ Backup selesai: $DATE" >> /var/log/backup.log
Setup Cron untuk Backup
# Buat script executable
chmod +x /var/www/iot-app/backup.sh
# Edit crontab
crontab -e
# Tambahkan: backup setiap jam 2 malam
0 2 * * * /var/www/iot-app/backup.sh
# Verifikasi cron terpasang
crontab -l
Restore dari Backup
# Restore aplikasi dari backup
cd /var/www/iot-app
tar -xzf /var/backups/iot/app_20260625_020000.tar.gz .
npm install --production
pm2 reload iot-api
# Restore database dari backup
gunzip -c /var/backups/iot/db_20260625_020000.sql.gz | psql -U iot_user iot_db
Install rclone untuk mengupload backup ke Google Drive, S3, Dropbox, atau MinIO: curl https://rclone.org/install.sh | sudo bash. Konfigurasi remote: rclone config. Ini memenuhi strategi backup 3-2-1 dengan menyimpan salinan offsite.
10. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang deploy ke VPS: