Membuat VPS Debian Bookworm di Virtual Box
Apa Itu VPS? Apa Maksudnya CLI Only & Akses SSH?
Apa itu VPS?
VPS (Virtual Private Server) adalah sebuah server virtual yang berjalan di atas mesin fisik menggunakan teknologi virtualisasi. Walaupun bersifat virtual, VPS bekerja layaknya server sungguhan:
- Memiliki sistem operasi sendiri
- Memiliki resource terisolasi (CPU, RAM, storage)
- Bisa diakses via jaringan
- Digunakan untuk menjalankan service seperti web server, API, database, dsb.
Dalam konteks tutorial ini, VPS tidak disewa dari cloud provider, melainkan dibuat secara lokal menggunakan VirtualBox. Tujuannya bukan menggantikan VPS production, tetapi untuk:
- Simulasi environment server
- Belajar administrasi Linux server
- Testing deployment backend
- Latihan hardening & networking
- Eksperimen tanpa biaya
Dengan pendekatan ini, kamu bisa memahami konsep VPS secara nyata sebelum terjun ke server publik.
Apa maksudnya CLI Only?
CLI Only (Command Line Interface only) berarti sistem Debian yang dipasang tanpa desktop environment atau GUI sama sekali. Yang tersedia hanyalah:
- Shell (bash)
- Command Linux
- Konfigurasi berbasis file teks
Pendekatan ini sengaja dipilih karena:
- Server production hampir selalu headless
- Lebih ringan (RAM & CPU jauh lebih hemat)
- Lebih aman (attack surface lebih kecil)
- Lebih dekat dengan kondisi VPS sungguhan
Dengan CLI-only, kamu dipaksa memahami:
- Struktur filesystem Linux
- Manajemen user & permission
- Service & daemon (systemd)
- Networking dasar
- Debugging via terminal
Singkatnya: tidak ada klik-klik, semuanya eksplisit.
Apa peran SSH dalam VPS?
SSH (Secure Shell) adalah protokol utama untuk mengakses VPS secara remote dengan aman. Dalam praktik nyata:
- VPS tidak diakses via monitor
- Semua administrasi dilakukan dari laptop/host
- SSH adalah “pintu masuk” utama ke server
Pada tutorial ini, SSH digunakan untuk:
- Login ke VPS dari host
- Mengelola server tanpa membuka VirtualBox UI
- Menerapkan best practice keamanan (disable root login, SSH key)
- Mensimulasikan workflow server production
Begitu SSH sudah dikonfigurasi dengan benar, VirtualBox praktis tidak perlu dibuka lagi. VPS bisa diperlakukan layaknya server sungguhan di data center.
Tujuan Tutorial Ini
Artikel ini bertujuan untuk:
- Membuat VPS Debian Bookworm v12 secara lokal
- Menggunakan pendekatan CLI only
- Mengakses dan mengelola server via SSH
- Membangun fondasi server yang aman dan rapi
- Menyiapkan VPS untuk deployment service (API, web, dsb.)
Tutorial ini bukan sekadar install OS, tapi membentuk mindset server sejak awal.
Prerequisites
Sebelum memulai, pastikan kamu memenuhi beberapa prasyarat berikut:
-
Sistem Operasi
- Windows, Linux, MacOS
- Artikel ini ditulis dan diuji menggunakan Ubuntu-based distro terutama Linux Mint
-
Perangkat Lunak
- Virtual Box (versi yang kugunakan ialah 7.0.16-dfsg-2ubuntu1.1)
Notes: Dalam kasus tertentu, matikan Secure Boot karena itu akan menyulitkan Virtual Box dalam mengakses Virtual OS. Untuk mematikannya, masuk ke firmware atau BIOS jika menggunakan Windows (sesuai preferensi PC masing-masing), lalu cari Secure Boot dan matikan. Fyi, Secure boot aman dimatikan jika kalian adalah developer.
-
Pengetahuan Dasar
Akan lebih mudah jika sudah memahami:
- Dasar Network
- Dasar terminal
- Konsep VPS
- Virtual Box
- Linux distro Debian
Langkah-langkah
Berikut ialah langkah-langkah konkret dalam pembuatan VPS Debian v12 CLI only dengan Virtual Box. Langkah-langkah berikut akan dipecah untuk beberapa tahap:
TAHAP 1: INSTALLASI
-
Download ISO Debian 12 Khusus Server
Gunakan netinst ISO karena paling umum dipakai dalam VPS. Berikut link download ISO Debian nya:
https://cdimage.debian.org/mirror/cdimage/archive/12.0.0/amd64/iso-cd/
Sesuaikan dengan preferensi OS masing-masing. Dalam kasus OS saya (Linux Mint AMD 64), saya memilih debian-12.0.0-amd64-netinst.iso
-
Buat Virtual Machine di Virtual Box
- Tekan tombol New
- Masukan nama bebas
- ISO Image pilih dari ISO yang telah didownload
- Sesuaikan hardware nya, misalnya RAM 1024 MB dan CPU 1 core
- Pilih hard disk VDI, Dynamically allocated, size 20 GB
- Setting network, adapter 1 ke bridged adapter, jika nanti gagal bisa fallback ke NAT
- Mount ISO, Storage pilih empty, ISO pilih debian 12 tadi
- lalu OK
-
Installasi Debian
- Pilih menu Install, karena butuh yang minimalis
- Buat hostname dengan nama bebas, beberapa aturan konvensinya ialah huruf kecil, angka, kebab-case. Contoh 192-server-lab (bisa diganti nanti)
- Isi domain jika ada, jika tidak ada maka kosongkan
- Isi full name bebas, berperan sebagai deskripsi
- Isi username sesuai dengan best practice, huruf kecil, angka, tanpa spasi. Hindari username root, test, user, admin, ubuntu
- Zona waktu pilih Indonesia
- Partition Disk tekan guided partitioning terus guided - use entire disk, lalu pilih SCSI2 (0,0,0) (sda) - 21.5 GB ATA VBOX HARDISK, lalu untuk skema partisi nya pilih All files in one partition. Setelah itu konfirmasi.
- Tidak perlu scan extra installation media
- Mirror country pilih Indonesia, jika tidak ada, pilih yang terdekat seperti Singapura. Mirror nya pilih deb.debian.org
- Untuk proxy kosongi jika tidak ada alamat proxy
- Configuring popularity contest itu opsional
- Pilih software yang diinstall, yaitu ssh server dan standard system utilities
- pilih yes pada
install the GRUB boot loader to your primary drive
TAHAP 2: SETTING DEBIAN
-
Masuk Sebagai Root
Login via SSH sebagai admin dengan:
su -Masukkan password root yang telah dibuat sebelumnya waktu installasi
Prompt akan berubah menjadi
root@debian-vps:-# -
Install Sudo
Dalam root, jalankan:
apt update apt install sudo -y -
Tambahkan User ke Sudo
Dalam root, jalankan:
usermod -aG sudo usernameSesuaikan username dengan username yang kamu buat.
Lalu cek dengan:
getent group sudoHarus ada:
sudo:x:27:usernamelalu logout dengan
exitMasuk lagi sebagai username, lalu test sudo dengan:
sudo whoamipastikan hasilnya
root -
Disable Root Login via SSH
Ini langkah keamanan no 1 di semua VPS.
Edit Config SSH dengan:
sudo nano /etc/ssh/sshd_configcari baris (bisa pakai Ctrl + W):
PermitRootLoginJika barisnya:
# PermitRootLogin prohibit-passwordUbah menjadi
PermitRootLogin noRestart SSH dengan:
sudo systemctl restart sshJangan langsung tutup session, test dengan
ssh root@IP_SERVERsesuaikan IP_SERVER dengan yang dimasukan sebelumnya, di saya ialah 192-server-lab.
Ketik yes jika outputnya:
The authenticity of host '192-server-lab (127.0.1.1)' can't be established. ED25519 key fingerprint is SHA256:xxxx This key is not known by any other names. Are you sure you want to continue connectingOpsional test:
masukkan password root lalu pastikan output nya permission denied. Jika iya, maka itu berhasil.
Bisa dicoba untuk login sebagai user normal, contohnya seperti:
ssh zul@192-server-labMasukkan password username, lalu pastikan berhasil masuk. Kemudan cek masuk root dengan:
sudo -iJika berhasil masuk ke root, maka sukses.
-
SSH Key Authentication
di HOST (laptop, bukan virtual OS), jalankan:
ssh-keygen -t ed25519Jika sudah ada SSH Keygen, misalnya dipakai di GitHub, maka biar aman buat SSH Keygen di file baru saja alih-alih overwrite dengan:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_serverlabsaat ditanya passphrase, boleh kosong atau isi aja supaya aman. (pastikan catat passphrase jika mengisi nya).
Copy key ke server dengan:
ssh-copy-id zul@IP_SERVERatau jika sebelumnya membuat file baru, maka seperti ini:
ssh-copy-id -i ~/.ssh/id_ed25519_serverlab.pub zul@IP_SERVERlalu masukkan password user dan pastikan masuk ke vps dengan akses user.
untuk IP_SERVER, bisa dilihat di virtual OS dengan:
ip alalu cari enp0s3, itnet atau sejenisnya tergantung preferensi network. atau alternatif jalankan:
hostname -Iopsional, biar lebih rapi alih-alih harus mengetik -i terus.
Di host, edit file:
nano ~/.ssh/configLalu isi dengan:
Host serverlab Hostname IP_SERVER User zul IdentityFile ~/.ssh/id_ed25519_serverlabsehingga, tiap kali login ke server cukup
ssh serverlabSekarang sudah bisa mengakses vps via host alih-alih di virtual OS.
-
Firewall (UFW)
Di server, install firewall dengan:
sudo apt update sudo apt install ufw -y sudo ufw allow OpenSSH sudo ufw enableCek dengan:
sudo ufw status verbosepastikan hasilnya:
Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip To Action From -- ------ ---- 22/tcp (OpenSSH) ALLOW IN Anywhere 22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6) -
Fail2ban (Anti Bruteforce)
Di server, install dengan:
sudo apt update sudo apt install fail2ban -yaktifkan dengan:
sudo systemctl enable --now fail2banTest fail2ban dengan:
sudo fail2ban-client statusharus muncul:
Jail list: sshdJika tidak aktif, besar kemungkinan karena fail2ban tidak menemukan file log. Jalankan perintah berikut untuk membuatnya:
sudo nano /etc/fail2ban/jail.localIsi dengan:
[DEFAULT] backend = systemd [sshd] enabled = truerestart fail2ban dengan:
sudo systemctl restart fail2banLalu cek statusnya dengan:
sudo systemctl status fail2banHarus muncul
Active: active (running)Lalu test lagi dan pastikan outputnya seperti yang diharapkan:
sudo fail2ban-client statusCek sshd nya dengan:
sudo fail2ban-client status sshdJika ada peringatan setting locale failed oleh perl waktu aktivasi fail2ban, itu bisa diabaikan atau jika risih, bisa fix locale dengan:
sudo dpkg-reconfigure localeslalu pilih en_US.UTF-8 dan id_ID.UTF-8, set en_US.UTF-8 sebagai default
-
Htop (monitoring dasar)
Di server, install dengan:
sudo apt update sudo install htop -yUntuk penggunaan htop nya, cukup
htopmaka akan muncul tampilan CLI untuk monitoring VPS
TAHAP 3: NGINX & PROXY
-
Install Nginx
Install Nginx dengan:
sudo apt update sudo apt install nginx -yCek dengan:
sudo systemctl status nginxPastikan:
Active: active (running) -
Izinkan HTTP di firewall
Jalankan command berikut pada server:
sudo ufw allow 'Nginx Full'Cek dengan:
sudo ufw status verbosedan pastikan harus ada:
80,443/tcp (Nginx Full) ALLOW IN Anywheretest di browser dengan
http://IP_SERVER. Pastikan muncul halaman welcome dari Nginx yang artinya sudah berhasil. -
Config Reverse Proxy
Notes:
Debian memakai pola:
/etc/nginx/ ├── sites-available/ ├── sites-enabled/bisa di cek dengan
ls la /etc/nginx/.Best practice:
- Jangan edit default langsung
- Buat file baru per service
Buat config:
sudo nano /etc/nginx/sites-available/serverlabIsi dengan:
server { listen 80; server_name _; 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; } }aktifkan config dengan
sudo ln -s /etc/nginx/sites-available/serverlab /etc/nginx/sites-enabled/Matikan default (best practices):
sudo rm /etc/nginx/sites-enabled/default -
Tes Reverse Proxy
Test config dan reload dengan:
sudo nginx -tJika outputnya ialah:
syntax is ok test is successfulmaka reload dengan:
sudo systemctl reload nginxTest pada browser dengan url
http://192.168.1.59/. Jika outputnya 502 Bad Gateway, maka itu normal (Nginx menunggu backend)
TAHAP 4: DEPLOY API
Dalam kasus ini, API akan menggunakan environment Node.js. Jika menggunakan environment lain seperti python, .NET, atau bahkan rust, bisa disesuaikan.
-
Installasi Node.js
Install Node.js dengan versi 20 LTS, jangan install Node bawaan apt karena versinya sudah tua.
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install ndodejs -yJika belum ada curl, install dengan
sudo apt install curl.Cek node dan npm nya dengan:
node -v npm -vs -
Buat Simple API
Ini hanya untuk testing saja, buat API dengan express langsung di server.
Jalankan perintah-perintah berikut:
mkdir ~/api-server cd ~/api-server npm init -y npm i express nano index.jsCopy program berikut ke index.js:
const express = require('express'); const app = express(); app.get('/', (req, res) => { res.json({ status: 'ok', message: 'meow' }); }); app.listen(3000, () => { console.log('API running on port 3000'); });Test manual dengan directory tetap di
~/api-server:node index.jsCek di VPS dengan
curl http://localhost:3000dan pastikan muncul message meow. Untuk di browser, cek dengan urlhttp://IP_SERVER, jika muncul meow, maka reverse proxy bekerja. -
Penggunaan PM2
PM2 Digunakan untuk memanage project Node.js dalam production. Install dengan:
sudo npm install -g pm2Jalankan dengan:
pm2 start index.js --name api-serverCek dengan:
pm2 statusBuat PM2 auto startup saat boot dengan:
pm2 startupIkuti command yang diberikan oleh PM2 (copy paste). Lalu simpan dengan:
pm2 saveUntuk logging di PM2, dapat dilakukan dengan salah satu dari 2 command berikut:
pm2 logs pm2 logs <nama-api> -
Penggunaan .env
Penggunaan env dalam ekosistem Node.js tetap memerlukan dotenv di source code lvl dan pm2 di vps lvl. Ubah sedikit source code dalam
~/api-server. Jalankan langkah2 berikutInstall dotenv di directory
~/api-serverdengan:npm i dotenvUpdate index.js dengan:
nano index.jsUpdate (copas) dengan:
require('dotenv').config(); const express = require('express'); const app = express(); const PORT = process.env.PORT || 3001; app.get('/', (req, res) => { res.json({ status: 'ok', message: 'meow', env: process.env.NODE_ENV, }); }); app.listen(PORT, () => { console.log(`API running on port ${PORT}`); });Buat file .env:
nano .envisi dengan:
PORT=3000 NODE_ENV=productionBuat ecosystem pm2 dengan:
pm2 ecosystemYang akan membuat
ecosystem.config.js. Edit itu dengan:nano ecosystem.config.jslalu isi dengan:
module.exports = { apps: [ { name: 'api-server', script: 'index.js', instances: 1, exec_mode: 'fork', watch: false, env: { NODE_ENV: 'production', } } ] };Dimana watch tidak perlu dalam production, CI/CD dalam pm2 juga tidak relevan dengan CI/CD modern, serta env dalam itu ialah override.
Beri keamanan env dengan:
chmod 600 .envItu akan mengunci file .env dimana hanya owner saja yang bisa read & write, bisa di cek dengan
ls -l .envsehingga muncul output .env seperti-rw-------Karena ada perubahan baru dalam ecosystem, maka API yang ada tidak cukup jika direstart hanya dengan
pm2 restart api-server, harus menghapus terlebih dahulu, menjalankan ecosystem, dan save dengan:pm2 delete api-server pm2 start ecosystem.config.js pm2 saveSekarang coba curl atau cek di browser dengan url API yang sama. Pastikan muncul variable json env.
Cheatsheet Singkat
Akses & User Management
| Tujuan | Perintah |
|---|---|
| Masuk root | su - |
| Update system | apt update && apt upgrade -y |
| Install | sudo apt install sudo -y |
| Tambah user ke sudo | usermod -aG sudo username |
| Cek sudo | group getent group sudo |
| Test sudo | sudo whoami |
SSH & Keamanan Dasar
| Tujuan | Perintah |
|---|---|
| Edit config SSH | sudo nano /etc/ssh/sshd_config |
| Disable root SSH | PermitRootLogin no |
| Restart SSH | sudo systemctl restart ssh |
| Test root login | ssh root@IP_SERVER |
| Login user | ssh username@IP_SERVER |
| Masuk root via sudo | sudo -i |
SSH Key Authentication (Host)
| Tujuan | Perintah |
|---|---|
| Generate SSH key | ssh-keygen -t ed25519 |
| Generate key khusus | ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_serverlab |
| Copy key ke server | ssh-copy-id user@IP_SERVER |
| Copy key custom | ssh-copy-id -i ~/.ssh/id_ed25519_serverlab.pub user@IP_SERVER |
| SSH config | nano ~/.ssh/config |
| Login via alias | ssh serverlab |
Networking & IP
| Tujuan | Perintah |
|---|---|
| Cek IP interface | ip a |
| Cek IP singkat | hostname -I |
Firewall (UFW)
| Tujuan | Perintah |
|---|---|
| Install UFW | sudo apt install ufw -y |
| Allow SSH | sudo ufw allow OpenSSH |
| Enable firewall | sudo ufw enable |
| Status firewall | sudo ufw status verbose |
Fail2Ban
| Tujuan | Perintah |
|---|---|
| Install Fail2Ban | sudo apt install fail2ban -y |
| Enable service | sudo systemctl enable --now fail2ban |
| Status Fail2Ban | sudo fail2ban-client status |
| Edit jail config | sudo nano /etc/fail2ban/jail.local |
| Restart Fail2Ban | sudo systemctl restart fail2ban |
| Status sshd jail | sudo fail2ban-client status sshd |
Monitoring
| Tujuan | Perintah |
|---|---|
| Install htop | sudo apt install htop -y |
| Run htop | htop |
Nginx & Reverse Proxy
| Tujuan | Perintah |
|---|---|
| Install Nginx | sudo apt install nginx -y |
| Cek status | sudo systemctl status nginx |
| Allow HTTP/HTTPS | sudo ufw allow 'Nginx Full' |
| Buat config | sudo nano /etc/nginx/sites-available/serverlab |
| Enable site | sudo ln -s /etc/nginx/sites-available/serverlab /etc/nginx/sites-enabled/ |
| Disable default | sudo rm /etc/nginx/sites-enabled/default |
| Test config | sudo nginx -t |
| Reload Nginx | sudo systemctl reload nginx |
Node.js & API
| Tujuan | Perintah |
|---|---|
| Install Node.js 20 | curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - |
| Install Node | sudo apt install nodejs -y |
| Cek Node | node -v |
| Cek NPM | npm -v |
| Init project | npm init -y |
| Install Express | npm i express |
| Run API | node index.js |
| Test API | curl http://localhost:3000 |
PM2 (Production)
| Tujuan | Perintah |
|---|---|
| Install PM2 | sudo npm install -g pm2 |
| Start app | pm2 start index.js --name api-server |
| Cek status | pm2 status |
| Enable startup | pm2 startup |
| Save process | pm2 save |
| Lihat logs | pm2 logs |
| Logs app tertentu | pm2 logs api-server |
Environment & PM2 Ecosystem
| Tujuan | Perintah |
|---|---|
| Install dotenv | npm i dotenv |
Buat .env | nano .env |
| Secure env | chmod 600 .env |
| Generate ecosystem | pm2 ecosystem |
| Edit ecosystem | nano ecosystem.config.js |
| Redeploy PM2 | pm2 delete api-server |
| Start ecosystem | pm2 start ecosystem.config.js |
| Save state | pm2 save |
Testing Akhir
| Tujuan | Perintah |
|---|---|
| Test local API | curl http://localhost:3000 |
| Test via Nginx | curl http://IP_SERVER |
| Test via browser | http://IP_SERVER |
Kesimpulan
Membangun VPS Debian Bookworm secara CLI-only di VirtualBox dengan akses SSH adalah pendekatan yang valid, realistis, dan mendidik, selama tujuannya jelas dan memahami keterbatasannya.
Pendekatan ini sangat cocok jika kamu:
- Ingin belajar dasar server & Linux secara serius
- Membutuhkan environment testing tanpa biaya
- Ingin memahami SSH, networking, dan hardening dasar
- Menyiapkan fondasi sebelum terjun ke VPS production
Namun, pendekatan ini bukan pengganti VPS cloud sungguhan, melainkan simulasi yang sangat mendekati. Untuk kebutuhan production, faktor seperti public IP, latency, dan high availability tetap membutuhkan cloud provider.
Singkatnya:
VPS lokal berbasis CLI bukan sekadar latihan, tapi fondasi mindset server yang benar.