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
ESP32 / Raspberry Pi / Sensor Node
β (MQTT / HTTP / WebSocket)
βΌ
βββββββββββββββββββββββββββββββ
β VPS (Ubuntu) β
β βββββββββββββββββββββββββ β
β β Nginx (443/80) β β
β β Reverse Proxy + SSL β β
β βββββββ¬βββββββββββ¬βββββββ β
β β β β
β βββββββΌβββ ββββββΌββββββ β
β βNode.js β β Grafana β β
β β API β βDashboard β β
β β :3000 β β :3001 β β
β βββββ¬βββββ ββββββββββββ β
β β β
β βββββΌβββββββββββ β
β β Database β β
β β (SQLite/ β β
β β PostgreSQL) β β
β ββββββββββββββββ β
βββββββββββββββββββββββββββββββ
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: