Panduan Lengkap Incus: Setup, Debug & Maintenance di Single Machine
Tutorial komprehensif Incus untuk pemula hingga expert. Pelajari cara install, konfigurasi, troubleshooting, dan maintenance container/VM di single machine untuk production VPS hosting.

Incus: Dari Nol Sampai Production-Ready
Kamu ingin menjalankan VPS hosting service? Atau butuh platform virtualisasi yang powerful untuk development? Incus adalah jawabannya.
Incus adalah fork dari LXD yang dikembangkan oleh Linux Containers. Berbeda dengan Docker yang fokus pada containerization aplikasi, Incus memungkinkan kamu menjalankan system container (seperti VM tapi lebih ringan) dan virtual machine penuh dalam satu platform.
Tutorial ini akan membawamu dari pemula menjadi expert dalam manajemen Incus.
Apa Itu Incus?
Perbedaan Container vs VM
| Aspek | System Container | Virtual Machine |
|---|---|---|
| Kernel | Shared dengan host | Sendiri (isolated) |
| Boot Time | Detik | Menit |
| Resource | Sangat ringan | Lebih berat |
| Isolation | Process-level | Hardware-level |
| Use Case | Web server, database | Windows, kernel khusus |
Kenapa Incus?
- Unified Management - Container dan VM dalam satu tool
- REST API - Automasi mudah dengan API
- Clustering - Scale ke multi-node dengan mudah
- Storage Backends - ZFS, Btrfs, LVM, Ceph
- Network Options - Bridge, OVN, macvlan, sriov
- Live Migration - Pindah instance tanpa downtime
- Open Source - Apache 2.0 license, community-driven
Part 1: Instalasi Incus
Prasyarat Sistem
# Cek CPU virtualization support (untuk VM)
egrep -c '(vmx|svm)' /proc/cpuinfo
# Output > 0 berarti didukung
# Cek kernel version (minimal 5.4+)
uname -r
# Cek RAM (minimal 2GB, rekomendasi 8GB+)
free -h
# Cek storage (rekomendasi SSD)
lsblk Instalasi di Ubuntu 22.04/24.04
Metode 1: Snap (Recommended untuk production)
# Install Incus dari snap
sudo snap install incus --channel=latest/stable
# Tambahkan user ke group incus-admin
sudo usermod -aG incus-admin $USER
# Logout dan login kembali, atau:
newgrp incus-admin Metode 2: Native Package (Ubuntu 24.04+)
# Add repository
sudo mkdir -p /etc/apt/keyrings/
curl -fsSL https://pkgs.zabbly.com/key.asc | sudo gpg --dearmor -o /etc/apt/keyrings/zabbly.gpg
sudo sh -c 'cat <<EOF > /etc/apt/sources.list.d/zabbly-incus-stable.sources
Enabled: yes
Types: deb
URIs: https://pkgs.zabbly.com/incus/stable
Suites: $(. /etc/os-release && echo ${VERSION_CODENAME})
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/zabbly.gpg
EOF'
# Install
sudo apt update
sudo apt install incus -y
# Add user to group
sudo usermod -aG incus-admin $USER
newgrp incus-admin Instalasi di Debian 12
# Install dependencies
sudo apt install curl gpg -y
# Add Zabbly repository
sudo mkdir -p /etc/apt/keyrings/
curl -fsSL https://pkgs.zabbly.com/key.asc | sudo gpg --dearmor -o /etc/apt/keyrings/zabbly.gpg
sudo sh -c 'cat <<EOF > /etc/apt/sources.list.d/zabbly-incus-stable.sources
Enabled: yes
Types: deb
URIs: https://pkgs.zabbly.com/incus/stable
Suites: bookworm
Components: main
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/zabbly.gpg
EOF'
sudo apt update
sudo apt install incus -y
sudo usermod -aG incus-admin $USER Part 2: Inisialisasi Incus
Interactive Setup
incus admin init Jawab pertanyaan-pertanyaan berikut:
Would you like to use clustering? no
Do you want to configure a new storage pool? yes
Name of the new storage pool: default
Name of the storage backend to use: zfs
Create a new ZFS pool? yes
Would you like to use an existing empty block device? no
Size in GiB of the new loop device (1GiB minimum): 50
Would you like to connect to a MAAS server? no
Would you like to create a new local network bridge? yes
What should the new bridge be called? incusbr0
What IPv4 address should be used? auto
What IPv6 address should be used? auto
Would you like the server to be available over the network? yes
Address to bind to: all
Port to bind to: 8443
Trust password for new clients: <set-password>
Would you like stale cached images to be updated automatically? yes
Would you like a YAML "init" preseed to be printed? yes Preseed untuk Automation
Simpan konfigurasi ke file untuk deployment cepat:
# incus-preseed.yaml
config:
core.https_address: '[::]:8443'
core.trust_password: 'your-secure-password'
networks:
- config:
ipv4.address: 10.10.10.1/24
ipv4.nat: "true"
ipv6.address: none
description: ""
name: incusbr0
type: bridge
storage_pools:
- config:
size: 100GiB
source: /var/lib/incus/storage-pools/default
description: ""
driver: zfs
name: default
profiles:
- config: {}
description: Default profile
devices:
eth0:
name: eth0
network: incusbr0
type: nic
root:
path: /
pool: default
type: disk
name: default Apply preseed:
cat incus-preseed.yaml | incus admin init --preseed Part 3: Konsep Dasar
Hierarki Objek di Incus
Incus Server
βββ Projects (namespace/isolation)
β βββ Instances (containers/VMs)
β β βββ Snapshots
β β βββ Backups
β βββ Images
β βββ Profiles
β βββ Networks
β βββ Storage Pools
βββ Cluster Members (multi-node) Instance Types
Container (System Container)
- Share kernel dengan host
- Boot dalam detik
- Resource overhead minimal
- Cocok untuk: web server, database, microservices
Virtual Machine
- Kernel sendiri (isolated)
- Bisa jalankan Windows, BSD
- Boot dalam menit
- Cocok untuk: OS berbeda, kernel testing
Profiles
Profile adalah template konfigurasi yang bisa di-attach ke instance:
# Lihat profile default
incus profile show default
# Buat profile baru
incus profile create web-server
# Edit profile
incus profile edit web-server Contoh profile untuk web server:
config:
limits.cpu: "2"
limits.memory: 2GiB
security.nesting: "false"
description: Web server profile
devices:
eth0:
name: eth0
network: incusbr0
type: nic
root:
path: /
pool: default
size: 20GiB
type: disk
name: web-server Part 4: Operasi Instance
Membuat Instance
Container dari Image
# List available images
incus image list images:
incus image list images: ubuntu
incus image list images: debian
# Launch Ubuntu 24.04 container
incus launch images:ubuntu/24.04 my-container
# Launch dengan profile khusus
incus launch images:ubuntu/24.04 web1 --profile web-server
# Launch dengan resource limits
incus launch images:ubuntu/24.04 web2
-c limits.cpu=2
-c limits.memory=4GiB Virtual Machine
# Launch Ubuntu VM
incus launch images:ubuntu/24.04 my-vm --vm
# VM dengan spesifikasi khusus
incus launch images:ubuntu/24.04 my-vm --vm
-c limits.cpu=4
-c limits.memory=8GiB
-d root,size=50GiB Lifecycle Management
# Start instance
incus start my-container
# Stop instance (graceful)
incus stop my-container
# Stop instance (force)
incus stop my-container --force
# Restart
incus restart my-container
# Pause (freeze)
incus pause my-container
# Delete instance
incus delete my-container
# Delete dengan force (termasuk yang running)
incus delete my-container --force Akses Instance
# Shell ke instance
incus exec my-container -- bash
# Run command
incus exec my-container -- apt update
# Run sebagai user tertentu
incus exec my-container -- su - ubuntu
# Console (untuk VM atau debug)
incus console my-vm
# Keluar: Ctrl+a q File Operations
# Copy file ke instance
incus file push local-file.txt my-container/tmp/
# Copy file dari instance
incus file pull my-container/etc/nginx/nginx.conf ./
# Copy directory
incus file push -r ./my-folder my-container/opt/
# Edit file langsung
incus file edit my-container/etc/hosts Resource Limits
# Set CPU limit
incus config set my-container limits.cpu=2
# Set memory limit
incus config set my-container limits.memory=4GiB
# Set disk quota
incus config device set my-container root size=30GiB
# Lihat konfigurasi
incus config show my-container
# Monitor resource usage
incus info my-container Part 5: Storage Management
Storage Pools
# List storage pools
incus storage list
# Info detail pool
incus storage info default
# Buat ZFS pool baru dengan disk dedicated
incus storage create fast zfs source=/dev/sdb
# Buat dir pool (simple, tidak recommended untuk production)
incus storage create backup dir source=/mnt/backup
# Buat LVM pool
incus storage create lvm-pool lvm source=volume-group-name Storage Volumes
# Buat volume untuk data persistent
incus storage volume create default data-vol
# Attach volume ke instance
incus storage volume attach default data-vol my-container /data
# Detach volume
incus storage volume detach default data-vol my-container
# Copy volume
incus storage volume copy default/data-vol default/data-vol-backup
# Delete volume
incus storage volume delete default data-vol Snapshots
# Buat snapshot
incus snapshot my-container snap1
# List snapshots
incus info my-container
# Restore snapshot
incus restore my-container snap1
# Delete snapshot
incus delete my-container/snap1
# Scheduled snapshots
incus config set my-container snapshots.schedule="@daily"
incus config set my-container snapshots.expiry="7d" Backups
# Buat backup (export)
incus export my-container my-container-backup.tar.gz
# Buat backup optimized (tanpa instance data)
incus export my-container my-container-backup.tar.gz --optimized-storage
# Import/restore backup
incus import my-container-backup.tar.gz restored-container
# Backup ke remote storage
incus export my-container - | ssh backup-server "cat > /backups/my-container.tar.gz" Part 6: Network Configuration
Network Types
| Type | Use Case | Isolation |
|---|---|---|
| bridge | Default, NAT internet | Moderate |
| macvlan | Direct LAN access | Low |
| sriov | High performance | Low |
| ovn | Software-defined, clustering | High |
Bridge Network (Default)
# List networks
incus network list
# Info network
incus network info incusbr0
# Edit network
incus network edit incusbr0
# Set DHCP range
incus network set incusbr0 ipv4.dhcp.ranges=10.10.10.100-10.10.10.200 Static IP Assignment
# Set static IP untuk instance
incus config device override my-container eth0 ipv4.address=10.10.10.50
# Atau via profile
incus profile device set my-profile eth0 ipv4.address=10.10.10.50 Port Forwarding
# Forward host port 8080 ke container port 80
incus config device add my-container http proxy
listen=tcp:0.0.0.0:8080
connect=tcp:127.0.0.1:80
# Forward range of ports
incus config device add my-container portrange proxy
listen=tcp:0.0.0.0:3000-3010
connect=tcp:127.0.0.1:3000-3010
# List proxy devices
incus config device show my-container Macvlan (Direct LAN)
# Buat macvlan network
incus network create macvlan0
ipv4.address=none
ipv6.address=none
parent=ens18
# Attach ke instance
incus config device add my-container eth0 nic
nictype=macvlan
parent=ens18
# Instance akan dapat IP dari router/DHCP LAN Part 7: Security & Isolation
Security Profiles
# Privileged container (NOT recommended, kecuali perlu)
incus config set my-container security.privileged=true
# Nesting (container dalam container, untuk Docker)
incus config set my-container security.nesting=true
# Isolate instance
incus config set my-container security.idmap.isolated=true User Namespace (UID/GID Mapping)
# Lihat mapping
incus config get my-container volatile.idmap.current
# Custom mapping
incus config set my-container raw.idmap="both 1000 1000" AppArmor & Seccomp
# Custom AppArmor profile
incus config set my-container raw.apparmor="..."
# Custom seccomp profile
incus config set my-container raw.seccomp="..." Resource Quotas
# CPU pinning
incus config set my-container limits.cpu=0,2 # Core 0 dan 2
# CPU priority (0-10, default 10)
incus config set my-container limits.cpu.priority=5
# Memory hard limit
incus config set my-container limits.memory=4GiB
# Memory soft limit (untuk overcommit)
incus config set my-container limits.memory.swap=false
# Disk I/O limits
incus config set my-container limits.disk.priority=5
# Network bandwidth
incus config device set my-container eth0 limits.ingress=100Mbit
incus config device set my-container eth0 limits.egress=100Mbit Part 8: Monitoring & Logging
Instance Metrics
# Info lengkap instance
incus info my-container
# Resource usage saat ini
incus info my-container --resources
# Processes dalam container
incus exec my-container -- top
# Disk usage
incus exec my-container -- df -h Built-in Metrics
# Enable metrics endpoint
incus config set core.metrics_address=:8444
# Access metrics (Prometheus format)
curl -k https://localhost:8444/1.0/metrics Log Management
# Lihat Incus daemon log
journalctl -u incus -f
# Instance console log
incus console my-container --show-log
# Incus operation log
incus operation list Monitoring dengan Prometheus
Tambahkan scrape config:
# prometheus.yml
scrape_configs:
- job_name: 'incus'
static_configs:
- targets: ['localhost:8444']
scheme: https
tls_config:
insecure_skip_verify: true Part 9: Debug & Troubleshooting
Diagnostic Commands
# Incus server status
incus admin status
# Check service
sudo systemctl status incus
# View daemon log
sudo journalctl -u incus -n 100
# Debug mode (verbose)
incus --debug list Common Issues & Solutions
Issue 1: Permission Denied
# Gejala
Error: Permission denied
# Solusi: Add user ke group
sudo usermod -aG incus-admin $USER
newgrp incus-admin Issue 2: Network Tidak Bekerja
# Cek bridge
ip addr show incusbr0
# Cek iptables
sudo iptables -t nat -L -n
# Cek firewall
sudo ufw status
# Allow forwarding
sudo sysctl net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf Issue 3: Storage Pool Full
# Cek usage
incus storage info default
# Untuk ZFS
sudo zpool list
sudo zfs list
# Cleanup unused images
incus image list
incus image delete <fingerprint>
# Cleanup snapshots
incus delete my-container/old-snapshot Issue 4: Instance Tidak Bisa Start
# Lihat error detail
incus start my-container --console
# Cek log
incus info my-container --show-log
# Force stop jika stuck
incus stop my-container --force
# Cek resource conflicts
incus info --resources Issue 5: VM Tidak Boot
# Cek UEFI/BIOS
incus config show my-vm | grep -i secureboot
# Disable secure boot jika perlu
incus config set my-vm security.secureboot=false
# Cek console output
incus console my-vm
# Akses VM console untuk debug
incus console my-vm --type=vga Issue 6: Image Download Gagal
# Cek koneksi ke image server
ping images.linuxcontainers.org
# Manual refresh
incus image refresh
# Download dengan verbose
incus image copy images:ubuntu/24.04 local: --debug Performance Debugging
# Storage performance
incus storage info default --resources
# ZFS stats
sudo zpool iostat -v 1
# Memory pressure
cat /proc/meminfo
free -h
# Container cgroup stats
cat /sys/fs/cgroup/incus.payload.my-container/memory.current Part 10: Maintenance Best Practices
Regular Maintenance Tasks
Harian:
# Cek status semua instance
incus list
# Cek resource usage
incus info --resources
# Review error logs
journalctl -u incus --since "1 day ago" -p err Mingguan:
# Update images
incus image refresh
# Cleanup unused images
incus image list --format=csv | while read line; do
fingerprint=$(echo $line | cut -d, -f2)
incus image delete $fingerprint 2>/dev/null
done
# Verify backups
ls -la /backup/incus/ Bulanan:
# Update Incus
sudo snap refresh incus
# atau
sudo apt update && sudo apt upgrade incus
# Storage maintenance (ZFS)
sudo zpool scrub default
sudo zpool status default
# Review dan cleanup snapshots lama
for instance in $(incus list -c n --format=csv); do
incus info $instance | grep -A 20 Snapshots
done Automated Backup Script
#!/bin/bash
# /usr/local/bin/incus-backup.sh
BACKUP_DIR="/backup/incus/$(date +%Y-%m-%d)"
RETENTION_DAYS=7
LOG_FILE="/var/log/incus-backup.log"
mkdir -p "$BACKUP_DIR"
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
log "Starting backup..."
# Backup semua running instances
for instance in $(incus list status=running -c n --format=csv); do
log "Backing up $instance..."
# Create snapshot
incus snapshot $instance backup-$(date +%H%M%S)
# Export
incus export $instance "$BACKUP_DIR/$instance.tar.gz" --optimized-storage
if [ $? -eq 0 ]; then
log "$instance backup completed"
else
log "ERROR: $instance backup failed"
fi
done
# Cleanup old backups
find /backup/incus -type d -mtime +$RETENTION_DAYS -exec rm -rf {} ; 2>/dev/null
log "Backup completed" Jadwalkan dengan cron:
# Edit crontab
crontab -e
# Tambahkan (backup jam 2 pagi setiap hari)
0 2 * * * /usr/local/bin/incus-backup.sh Health Check Script
#!/bin/bash
# /usr/local/bin/incus-healthcheck.sh
# Cek Incus service
if ! systemctl is-active --quiet incus; then
echo "CRITICAL: Incus service not running"
systemctl restart incus
fi
# Cek storage pool health
POOL_STATUS=$(incus storage info default | grep -i status)
if [[ ! "$POOL_STATUS" =~ "Created" ]]; then
echo "WARNING: Storage pool issue detected"
fi
# Cek stopped instances yang seharusnya running
for instance in $(incus list status=stopped -c n --format=csv); do
AUTO_START=$(incus config get $instance boot.autostart)
if [ "$AUTO_START" = "true" ]; then
echo "WARNING: $instance stopped but has autostart"
incus start $instance
fi
done
# Cek disk usage
DISK_USAGE=$(df -h / | tail -1 | awk '{print $5}' | tr -d '%')
if [ $DISK_USAGE -gt 85 ]; then
echo "WARNING: Disk usage at $DISK_USAGE%"
fi
echo "Health check completed at $(date)" Security Hardening
# 1. Disable remote access jika tidak perlu
incus config unset core.https_address
incus config unset core.trust_password
# 2. Use certificate auth instead of password
incus config set core.https_address=[::]:8443
incus config trust add-certificate client.crt
# 3. Enable security features
incus config set core.https_allowed_credentials=false
incus config set core.https_allowed_headers=""
incus config set core.https_allowed_methods=""
# 4. Audit log
incus config set core.log_level=debug
# 5. Instance defaults
incus profile set default security.privileged=false
incus profile set default security.nesting=false Part 11: Production Checklist
Pre-Production Checklist
- Storage: ZFS atau LVM dengan redundancy
- Network: Bridge dengan firewall rules
- Backup: Automated backup dengan retention
- Monitoring: Prometheus + Grafana setup
- Alerting: Alert untuk service down, disk full
- Security: Non-privileged containers, firewall
- Documentation: Instance inventory, network diagram
- DR Plan: Backup restore procedure tested
Instance Template untuk VPS
# vps-template.yaml
config:
boot.autostart: "true"
limits.cpu: "2"
limits.memory: 4GiB
security.nesting: "false"
security.privileged: "false"
user.user-data: |
#cloud-config
package_update: true
packages:
- curl
- wget
- vim
- htop
users:
- name: customer
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
ssh_authorized_keys:
- ssh-rsa CUSTOMER_SSH_KEY
description: VPS Customer Template
devices:
eth0:
name: eth0
network: incusbr0
type: nic
root:
path: /
pool: default
size: 20GiB
type: disk
name: vps-template Provisioning Script
#!/bin/bash
# create-vps.sh
CUSTOMER_NAME=$1
CPU=${2:-2}
RAM=${3:-4GiB}
DISK=${4:-20GiB}
if [ -z "$CUSTOMER_NAME" ]; then
echo "Usage: $0 <customer-name> [cpu] [ram] [disk]"
exit 1
fi
INSTANCE_NAME="vps-$CUSTOMER_NAME"
# Launch instance
incus launch images:ubuntu/24.04 $INSTANCE_NAME
--profile default
-c limits.cpu=$CPU
-c limits.memory=$RAM
-d root,size=$DISK
-c boot.autostart=true
# Wait for boot
sleep 5
# Setup basic security
incus exec $INSTANCE_NAME -- bash -c "
apt update
apt install -y ufw fail2ban
ufw default deny incoming
ufw default allow outgoing
ufw allow ssh
ufw --force enable
systemctl enable fail2ban
"
# Get IP
IP=$(incus list $INSTANCE_NAME -c 4 --format=csv | cut -d' ' -f1)
echo "VPS Created!"
echo "Instance: $INSTANCE_NAME"
echo "IP: $IP"
echo "Specs: $CPU CPU, $RAM RAM, $DISK Disk" Penutup
Dengan panduan ini, kamu sudah punya foundation yang solid untuk mengelola Incus di single machine. Key takeaways:
- Incus = Container + VM dalam satu platform
- Storage: Pilih ZFS untuk production
- Network: Bridge untuk simple, OVN untuk complex
- Security: Non-privileged by default
- Backup: Automate dengan script + cron
- Monitor: Gunakan Prometheus + Grafana
Untuk skala yang lebih besar, lanjut ke tutorial Incus Cluster Setup untuk belajar:
- Multi-node clustering
- MicroOVN untuk software-defined networking
- MicroCeph untuk distributed storage
- High availability dan live migration
Butuh VPS yang sudah siap pakai? Tidak perlu setup sendiri - langsung pakai VPS Dalang.io dengan akses via web browser!
Ada pertanyaan? Hubungi [email protected]
