Incus Installation Guide

Incus is a free and open-source system container and virtual machine manager. It's a community-driven fork of LXD that maintains true open-source governance, serving as a FOSS alternative to proprietary virtualization platforms like VMware vSphere, Proxmox, or cloud-based container services.

VirtualizationπŸ”΄ advanced11 min⏱️ 30-60 minutes

Incus is a free and open-source system container and virtual machine manager. It's a community-driven fork of LXD, created to maintain true open-source governance after Canonical moved LXD development in-house. Incus serves as a FOSS alternative to proprietary virtualization platforms like VMware vSphere, Proxmox (with subscription limitations), or cloud-based container services, providing powerful system containers and VMs with enterprise-grade features.

1. Prerequisites

Hardware Requirements

  • CPU: Modern 64-bit processor with virtualization support (VT-x/AMD-V)
  • RAM: 2GB minimum (4GB+ recommended)
  • Storage: 20GB+ available space
  • Network: Ethernet interface for bridged networking
  • Software Requirements

  • Kernel: Linux 5.4+ with namespaces and cgroup support
  • Storage: ZFS, LVM, or directory backend support
  • Network: Bridge utilities for networking
  • Network Requirements

  • Ports:
  • 8443: HTTPS API (default)
  • Various: Container/VM networking
  • Bridge: Network bridge for container connectivity
  • 2. Supported Operating Systems

    Incus officially supports:

  • RHEL 9+ and derivatives (Rocky Linux, AlmaLinux)
  • Debian 11/12
  • Ubuntu 20.04 LTS / 22.04 LTS / 24.04 LTS
  • Arch Linux
  • Alpine Linux 3.18+
  • openSUSE Leap 15.5+ / Tumbleweed
  • Fedora 38+
  • 3. Installation

    RHEL/Rocky Linux/AlmaLinux

    bash
    # Install EPEL repository
    sudo dnf install -y epel-release
    
    # Install dependencies
    sudo dnf install -y snapd bridge-utils dnsmasq
    
    # Enable and start snapd
    sudo systemctl enable --now snapd
    sudo ln -sf /var/lib/snapd/snap /snap
    
    # Install Incus via snap
    sudo snap install incus --channel=latest/stable
    
    # Add user to incus group
    sudo usermod -a -G snap_daemon $USER
    newgrp snap_daemon
    
    # Initialize Incus
    sudo incus admin init

    Debian/Ubuntu

    bash
    # Update system
    sudo apt update
    
    # Install dependencies
    sudo apt install -y snapd bridge-utils dnsmasq-base
    
    # Install Incus via snap
    sudo snap install incus --channel=latest/stable
    
    # Alternative: Install from Zabbly repository (recommended)
    curl -fsSL https://pkgs.zabbly.com/key.asc | sudo gpg --dearmor -o /etc/apt/keyrings/zabbly.gpg
    echo "deb [signed-by=/etc/apt/keyrings/zabbly.gpg] https://pkgs.zabbly.com/incus/stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/zabbly-incus-stable.list
    
    sudo apt update
    sudo apt install -y incus
    
    # Add user to incus group
    sudo usermod -a -G incus $USER
    newgrp incus
    
    # Initialize Incus
    incus admin init

    Arch Linux

    bash
    # Install from AUR
    yay -S incus
    
    # Or using official repositories (if available)
    sudo pacman -S incus
    
    # Enable and start service
    sudo systemctl enable --now incus
    
    # Add user to incus group
    sudo usermod -a -G incus $USER
    newgrp incus
    
    # Initialize Incus
    incus admin init

    Alpine Linux

    bash
    # Install from edge repositories
    echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
    apk update
    
    # Install Incus
    apk add incus
    
    # Enable and start service
    rc-service incus start
    rc-update add incus default
    
    # Add user to incus group
    addgroup $USER incus
    
    # Initialize Incus
    incus admin init

    openSUSE

    bash
    # Install dependencies
    sudo zypper install -y snapd bridge-utils dnsmasq
    
    # Enable snapd
    sudo systemctl enable --now snapd
    sudo ln -sf /var/lib/snapd/snap /snap
    
    # Install Incus
    sudo snap install incus --channel=latest/stable
    
    # Add user to incus group
    sudo usermod -a -G snap_daemon $USER
    newgrp snap_daemon
    
    # Initialize Incus
    sudo incus admin init

    4. Configuration

    Initial Setup (incus admin init)

    bash
    # Run interactive initialization
    incus admin init
    
    # Example configuration responses:
    # Would you like to use clustering? (yes/no) [default=no]: no
    # Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
    # Name of the new storage pool [default=default]: default
    # Name of the storage backend to use (dir, lvm, zfs) [default=zfs]: zfs
    # Create a new ZFS pool? (yes/no) [default=yes]: yes
    # Would you like to use an existing empty block device? (yes/no) [default=no]: no
    # Size in GB of the new loop device (1GB minimum) [default=5GB]: 20GB
    # Would you like to connect to a MAAS server? (yes/no) [default=no]: no
    # Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
    # What should the new bridge be called? [default=incusbr0]: incusbr0
    # What IPv4 address should be used? [default=auto]: auto
    # What IPv6 address should be used? [default=auto]: auto

    Storage Configuration

    bash
    # List storage pools
    incus storage list
    
    # Create ZFS storage pool
    incus storage create zfspool zfs size=50GB
    
    # Create directory storage pool
    incus storage create dirpool dir source=/var/lib/incus/storage-pools/dirpool
    
    # Create LVM storage pool
    incus storage create lvmpool lvm source=/dev/sdb

    Network Configuration

    bash
    # List networks
    incus network list
    
    # Create managed network
    incus network create incusbr1 \
        ipv4.address=192.168.100.1/24 \
        ipv4.nat=true \
        ipv6.address=fd00::1/64 \
        ipv6.nat=true
    
    # Create macvlan network
    incus network create macvlan1 \
        parent=eth0 \
        type=macvlan

    Profile Configuration

    bash
    # List profiles
    incus profile list
    
    # Create custom profile
    incus profile create webserver
    incus profile edit webserver
    
    # Example profile configuration:
    cat << 'EOF' | incus profile edit webserver
    config:
      limits.cpu: "2"
      limits.memory: 2GB
      security.nesting: "true"
    description: Web server profile
    devices:
      eth0:
        name: eth0
        network: incusbr0
        type: nic
      root:
        path: /
        pool: default
        type: disk
    name: webserver
    EOF

    5. Service Management

    System Service Management

    bash
    # systemd (most distributions)
    sudo systemctl start incus
    sudo systemctl enable incus
    sudo systemctl status incus
    sudo systemctl restart incus
    
    # Check service logs
    sudo journalctl -u incus -f
    
    # OpenRC (Alpine)
    sudo rc-service incus start
    sudo rc-update add incus default

    Container/VM Management

    bash
    # List instances
    incus list
    
    # Launch container
    incus launch ubuntu:22.04 mycontainer
    
    # Launch VM
    incus launch ubuntu:22.04 myvm --vm
    
    # Start/stop instances
    incus start mycontainer
    incus stop mycontainer
    incus restart mycontainer
    
    # Execute commands in container
    incus exec mycontainer -- bash
    incus exec mycontainer -- apt update
    
    # File operations
    incus file push localfile mycontainer/remote/path/
    incus file pull mycontainer/remote/path/file localfile

    Instance Configuration

    bash
    # Set instance limits
    incus config set mycontainer limits.cpu 2
    incus config set mycontainer limits.memory 1GB
    
    # Add devices
    incus config device add mycontainer homedir disk source=/home path=/mnt/home
    
    # Set environment variables
    incus config set mycontainer environment.MYVAR myvalue
    
    # View instance configuration
    incus config show mycontainer

    6. Troubleshooting

    Common Issues

    1. Incus daemon not starting:

    bash
    # Check system requirements
    sudo incus admin init --dump
    
    # Check logs
    sudo journalctl -u incus -n 50
    
    # Reset configuration
    sudo incus admin init --auto

    2. Network connectivity issues:

    bash
    # Check bridge status
    ip link show incusbr0
    
    # Test network connectivity
    incus exec mycontainer -- ping 8.8.8.8
    
    # Restart network
    sudo systemctl restart incus

    3. Storage issues:

    bash
    # Check storage pools
    incus storage list
    incus storage info default
    
    # Check disk space
    df -h /var/lib/incus
    
    # Repair ZFS pool
    sudo zpool scrub default

    4. Permission errors:

    bash
    # Check user groups
    groups $USER
    
    # Add user to incus group
    sudo usermod -a -G incus $USER
    newgrp incus
    
    # Check socket permissions
    ls -la /var/lib/incus/unix.socket

    Debug Mode

    bash
    # Enable debug logging
    incus config set core.https_address :8443
    incus config set core.debug true
    
    # Run daemon in foreground
    sudo incusd --debug --group incus
    
    # Check daemon status
    incus info

    7. Security Considerations

    Access Control

    bash
    # Set up TLS authentication
    incus config trust add client.crt
    
    # Generate client certificate
    openssl req -x509 -newkey rsa:4096 -keyout client.key -out client.crt -days 365 -nodes
    
    # Add trust relationship
    incus config trust add client.crt

    Network Security

    bash
    # Configure firewall for API access
    sudo firewall-cmd --permanent --add-port=8443/tcp
    sudo firewall-cmd --reload
    
    # UFW (Ubuntu/Debian)
    sudo ufw allow 8443/tcp
    sudo ufw enable
    
    # Bind to specific interface
    incus config set core.https_address 192.168.1.100:8443

    Container Security

    bash
    # Enable security features
    incus profile set default security.nesting false
    incus profile set default security.privileged false
    incus profile set default security.seccomp true
    
    # Set resource limits
    incus profile set default limits.cpu 2
    incus profile set default limits.memory 1GB
    incus profile set default limits.processes 1000

    Storage Security

    bash
    # Enable ZFS encryption
    incus storage create encrypted zfs \
        source=/dev/sdb \
        zfs.pool_name=encrypted \
        zfs.encryption=aes-256-gcm
    
    # Set secure permissions
    sudo chmod 700 /var/lib/incus
    sudo chown -R root:incus /var/lib/incus

    8. Performance Tuning

    CPU Optimization

    bash
    # Set CPU scheduler for containers
    incus config set mycontainer limits.cpu.allowance 50%
    incus config set mycontainer limits.cpu.priority 5
    
    # Pin to specific CPUs
    incus config set mycontainer limits.cpu 0-3

    Memory Optimization

    bash
    # Configure memory limits
    incus config set mycontainer limits.memory 2GB
    incus config set mycontainer limits.memory.swap false
    
    # Enable memory ballooning for VMs
    incus config set myvm limits.memory.enforce hard

    Storage Performance

    bash
    # Optimize ZFS for SSDs
    sudo zpool set autotrim=on default
    
    # Set ZFS recordsize for databases
    incus storage set default zfs.pool_name default
    incus storage volume set default myvolume zfs.recordsize 8K
    
    # Enable compression
    incus storage set default zfs.compression lz4

    Network Optimization

    bash
    # Increase network buffer sizes
    echo 'net.core.rmem_max = 16777216' | sudo tee -a /etc/sysctl.conf
    echo 'net.core.wmem_max = 16777216' | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p
    
    # Use SR-IOV for VMs (if supported)
    incus config device add myvm eth0 nic \
        nictype=sriov \
        parent=eth0

    9. Backup and Restore

    Instance Backup

    bash
    #!/bin/bash
    # backup-incus-instances.sh
    
    BACKUP_DIR="/var/backups/incus"
    DATE=$(date +%Y%m%d_%H%M%S)
    
    mkdir -p $BACKUP_DIR
    
    # Export all instances
    for instance in $(incus list -c n --format csv); do
        echo "Backing up $instance..."
        incus export $instance "$BACKUP_DIR/${instance}_${DATE}.tar.gz" \
            --instance-only
    done
    
    echo "Instance backups completed in $BACKUP_DIR"

    Storage Backup

    bash
    #!/bin/bash
    # backup-incus-storage.sh
    
    BACKUP_DIR="/var/backups/incus"
    DATE=$(date +%Y%m%d_%H%M%S)
    
    # ZFS snapshot backup
    sudo zfs snapshot default@backup_$DATE
    
    # Export ZFS snapshot
    sudo zfs send default@backup_$DATE | \
        gzip > $BACKUP_DIR/zfs_backup_$DATE.gz
    
    echo "Storage backup completed"

    Configuration Backup

    bash
    #!/bin/bash
    # backup-incus-config.sh
    
    BACKUP_DIR="/var/backups/incus"
    DATE=$(date +%Y%m%d_%H%M%S)
    
    # Backup database
    sudo systemctl stop incus
    sudo cp -r /var/lib/incus/database $BACKUP_DIR/database_$DATE
    sudo systemctl start incus
    
    # Export configuration
    incus admin export > $BACKUP_DIR/incus_config_$DATE.yaml
    
    echo "Configuration backup completed"

    Restore Procedures

    bash
    # Restore instance
    incus import instance_backup.tar.gz
    
    # Restore from ZFS snapshot
    sudo zfs rollback default@backup_20250916
    
    # Restore configuration
    incus admin import < incus_config_backup.yaml

    10. System Requirements

    Minimum Requirements

  • CPU: 2 cores, 2.0 GHz
  • RAM: 2GB
  • Storage: 20GB
  • Network: 100 Mbps
  • CPU: 4+ cores, 3.0+ GHz
  • RAM: 8GB+
  • Storage: 100GB+ SSD
  • Network: Gigabit Ethernet
  • Scaling Guidelines

  • Per container: ~100MB RAM overhead
  • Per VM: ~512MB RAM overhead
  • Storage: Plan for snapshot storage (20-50% overhead)
  • 11. Support

    Official Resources

  • Website: https://linuxcontainers.org/incus/
  • GitHub: https://github.com/lxc/incus
  • Documentation: https://linuxcontainers.org/incus/docs/
  • Forum: https://discuss.linuxcontainers.org
  • Community Support

  • Matrix: #incus:matrix.org
  • IRC: #lxc on libera.chat
  • GitHub Issues: https://github.com/lxc/incus/issues
  • 12. Contributing

    How to Contribute

    1. Fork the repository on GitHub

    2. Create a feature branch

    3. Submit pull request

    4. Follow Go coding standards

    5. Include tests and documentation

    Development Setup

    bash
    # Clone repository
    git clone https://github.com/lxc/incus.git
    cd incus
    
    # Install Go dependencies
    make deps
    
    # Build Incus
    make
    
    # Run tests
    make check

    13. License

    Incus is licensed under the Apache License 2.0.

    Key points:

  • Free to use, modify, and distribute
  • Commercial use allowed
  • No copyleft requirements
  • Patent grant included
  • 14. Acknowledgments

    Credits

  • Incus Team: Core development team led by StΓ©phane Graber
  • LXC Project: Container runtime foundation
  • Linux Containers: Project hosting and governance
  • Community Contributors: Feature development and testing
  • 15. Version History

    Current Releases

  • v6.x LTS: Long-term support until 2029
  • v0.x: Monthly feature releases
  • Major Features by Version

  • v6.0: LTS release with clustering improvements
  • v0.5: Enhanced VM support
  • v0.1: Initial fork from LXD
  • 16. Appendices

    A. Migration from LXD

    bash
    # Install migration tool
    sudo snap install lxd-to-incus
    
    # Stop LXD
    sudo snap stop lxd
    
    # Run migration
    sudo lxd-to-incus
    
    # Verify migration
    incus list
    incus info

    B. Clustering Setup

    bash
    # Initialize cluster on first node
    incus admin init
    
    # Join additional nodes
    incus admin init
    
    # List cluster members
    incus cluster list
    
    # Add node to cluster
    incus cluster add node2

    C. API Examples

    bash
    # Get instance list via API
    curl -k -H "Authorization: Bearer $TOKEN" \
        https://localhost:8443/1.0/instances
    
    # Create instance via API
    curl -k -X POST -H "Content-Type: application/json" \
        -H "Authorization: Bearer $TOKEN" \
        -d '{"name":"test","source":{"type":"image","alias":"ubuntu/22.04"}}' \
        https://localhost:8443/1.0/instances

    D. Performance Monitoring

    bash
    #!/bin/bash
    # monitor-incus.sh
    
    echo "=== Incus Status ==="
    incus info
    
    echo -e "\n=== Instance Status ==="
    incus list
    
    echo -e "\n=== Storage Usage ==="
    incus storage info default
    
    echo -e "\n=== Network Status ==="
    incus network list
    
    echo -e "\n=== System Resources ==="
    free -h
    df -h /var/lib/incus

    ---

    For more information and updates, visit https://github.com/howtomgr/incus