Installation Guide

Complete guide to installing Infinibay VDI platform on Ubuntu and Fedora

Installation Guide

Introduction

Infinibay manages virtual machines on Linux hosts using QEMU/KVM via Infinization (a TypeScript QEMU command builder). Libvirt is used for network filtering (firewall) and network bridge management.

Installation guide for Ubuntu 23.10+ and Fedora 37+.

For detailed technical reference, see the installer repository.

Installation Methods

Infinibay offers two installation methods:

Status: In active development - ready in weeks

The easiest way to deploy Infinibay is using LXD containers with lxc/lxd-compose. This method provides:

  • One-command deployment: lxc launch infinibay or lxd-compose up
  • Isolated environment: Complete isolation from host system
  • Easy updates: Simple container image updates
  • Resource limits: Built-in CPU/memory constraints
  • Snapshots: Instant backup and restore
  • Minimal host changes: No system package modifications

Best for: Production deployments, testing, isolated environments

For the latest LXD deployment status, see the LXD repository.

πŸ“¦ Direct Installation (Available Now)

Traditional installation directly on the host system. Provides maximum performance and full system access but modifies system packages and services.

Best for: Development, bare-metal performance, custom configurations

Continue reading below for direct installation instructions.

System Requirements

Supported Operating Systems

  • Ubuntu 23.10 or later
  • Fedora 37 or later

Hardware Requirements

  • CPU: x86_64 processor with hardware virtualization support (Intel VT-x or AMD-V)
    • egrep -c '(vmx|svm)' /proc/cpuinfo (should return > 0)
  • RAM: Minimum 8GB (16GB+ recommended for running multiple VMs)
  • Disk Space:
    • 10GB minimum for /opt/infinibay/ (code and dependencies)
    • Additional space for VM disk images (varies by usage)
    • Recommended: 100GB+ SSD for optimal VM performance

Software Prerequisites

  • Python 3.8 or later: Required for running the installer
  • Root/sudo access: Installation modifies system packages and services
  • Internet connectivity: Required for downloading packages, repositories, and ISOs

Optional Dependencies

  • asciimatics: Enhances installation banner
    pip3 install asciimatics
    

Pre-Installation Checklist

Verify system requirements:

# Verify KVM support (should return > 0)
egrep -c '(vmx|svm)' /proc/cpuinfo

# Check disk space (ensure 10GB+ free in /opt)
df -h /opt

# Verify Python version (should be 3.8+)
python3 --version

# Ensure sudo access
sudo -v

# Check OS version
cat /etc/os-release

Direct Installation Guide

Note: This section covers traditional direct installation. For LXD container deployment (recommended when available), see the section above.

Basic Installation

# Clone the installer repository
git clone https://github.com/infinibay/installer.git
cd installer

# Run the installer
sudo python3 install.py

What happens automatically:

  • Detects host IP
  • Generates database password
  • Uses default libvirt network
  • Installs to /opt/infinibay/
  • Creates systemd services
  • Configures PostgreSQL
  • Builds repositories

Installation Summary

At the end of installation, you'll see a summary (example output, values may differ if flags are used):

╔═══════════════════════════════════════════════════════════════╗
β•‘              INFINIBAY INSTALLATION COMPLETE!                  β•‘
╠═══════════════════════════════════════════════════════════════╣
β•‘ Frontend URL:      http://192.168.1.100:3000                  β•‘
β•‘ Backend URL:       http://192.168.1.100:4000                  β•‘
β•‘ GraphQL Playground: http://192.168.1.100:4000/graphql         β•‘
β•‘                                                                β•‘
β•‘ Admin Credentials:                                             β•‘
β•‘   Email:    admin@example.com                                  β•‘
β•‘   Password: password                                           β•‘
β•‘                                                                β•‘
β•‘ Database Password: [generated password shown here]             β•‘
β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

Save these credentials for accessing the web interface.

Installation Options

Custom Database Configuration

# Custom password
sudo python3 install.py --db-password=MySecurePassword123

# Remote PostgreSQL
sudo python3 install.py --db-host=192.168.1.50 --db-port=5432

# Custom database and user names
sudo python3 install.py --db-name=infinibay_prod --db-user=infinibay_prod

Network Configuration

# Specify host IP
sudo python3 install.py --host-ip=192.168.1.100

# Use specific libvirt network
sudo python3 install.py --libvirt-network-name=br0

Custom Ports

sudo python3 install.py --backend-port=8080 --frontend-port=8081

Custom Installation Directory

# Custom install directory
sudo python3 install.py --install-dir=/opt/custom/path

# Separate data directory for VM disks/ISOs
sudo python3 install.py --install-dir=/opt/infinibay --data-dir=/mnt/storage/infinibay

Execution Modes

# Dry run
sudo python3 install.py --dry-run

# Verbose logging
sudo python3 install.py --verbose

# Combined
sudo python3 install.py --dry-run --verbose

Complete Example

sudo python3 install.py \
  --host-ip=192.168.1.100 \
  --db-password=SecurePass2024! \
  --libvirt-network-name=br0 \
  --backend-port=4000 \
  --frontend-port=3000 \
  --install-dir=/opt/infinibay \
  --data-dir=/mnt/storage/infinibay \
  --skip-windows-isos \
  --verbose

Development Mode Installation

Development mode: Install from local workspace instead of cloning from GitHub.

cd /home/andres/infinibay
sudo python3 installer/install.py --install-dir=/home/andres/infinibay

Or use the helper script:

cd /home/andres/infinibay
sudo ./installer/install-dev.sh

The installer detects existing .git directories and skips cloning, builds in place, and restores file ownership after builds.

Understanding the Installation Process

The Infinibay installer executes five distinct phases in sequence. Understanding what each phase does helps with troubleshooting, customization, and learning how the system works.

Installation Phases Overview

Phase Name Duration Purpose
1 Framework Initialization < 1 min Validate environment, detect configuration
2 System Dependencies 5-10 min Install packages (Node.js, PostgreSQL, QEMU, Rust)
3 Database Setup 1-2 min Create PostgreSQL user and database
4 Repository Setup 10-20 min Clone and build all components
5 Configuration & Services 5-10 min Generate configs, run migrations, start services

Total estimated time: 20-40 minutes (depending on internet speed and system performance)


Phase 1: Framework Initialization

Purpose: Validate the installation environment and gather configuration parameters.

What it does:

  • Detects operating system type and version (Ubuntu 23.10+ or Fedora 37+)
  • Validates OS compatibility against minimum version requirements
  • Checks for root/sudo privileges (required for system modifications)
  • Auto-detects host IP address for VM connectivity
  • Generates secure random database password (if not provided via --db-password)
  • Creates installation context with all configuration parameters
  • Prompts for admin credentials if using defaults

Key validations:

  • OS version check: Ensures Ubuntu β‰₯ 23.10 or Fedora β‰₯ 37
  • Privilege verification: Confirms script is running as root/sudo
  • Network interface detection: Finds primary network interface and IP address

Configuration gathered:

  • Installation paths (--install-dir, --data-dir)
  • Database credentials (--db-user, --db-password, --db-host, --db-port)
  • Network settings (--host-ip, --libvirt-network-name)
  • Service ports (--backend-port, --frontend-port)
  • Admin user credentials (--admin-email, --admin-password)

Source: file:installer/install.py (lines 150-218), file:installer/lib/os_detect.py, file:installer/lib/config.py


Phase 2: System Dependencies

Purpose: Install all required system packages and tools.

What it does:

  1. Updates package manager cache (apt update or dnf check-update)
  2. Installs system packages (see tables below)
  3. Initializes PostgreSQL database cluster (Fedora only)
  4. Enables and starts PostgreSQL service
  5. Installs Rust toolchain via rustup (not system packages)
  6. Verifies all required commands are available
  7. Checks KVM virtualization support
  8. Adds user to kvm group for /dev/kvm access

Packages installed by OS:

Ubuntu/Debian Packages

Package Purpose
nodejs, npm Node.js 18+ runtime and package manager
postgresql, postgresql-contrib PostgreSQL database server
qemu-kvm QEMU/KVM virtualization
bridge-utils, cpu-checker Network bridging and KVM verification
build-essential, pkg-config C/C++ compiler and build tools
libssl-dev OpenSSL development headers
mingw-w64 Windows cross-compilation toolchain
btrfs-progs, p7zip-full Filesystem and compression utilities
curl Download tool (for rustup installation)

Fedora Packages

Package Purpose
nodejs, npm Node.js 18+ runtime and package manager
postgresql, postgresql-server PostgreSQL database server
qemu-kvm QEMU/KVM virtualization
bridge-utils Network bridging utilities
gcc, gcc-c++, make C/C++ compiler and build tools
pkg-config, openssl-devel Build configuration and OpenSSL headers
mingw64-gcc Windows cross-compilation toolchain
btrfs-progs, p7zip Filesystem and compression utilities
curl Download tool (for rustup installation)

Rust installation:

  • Installed via rustup (official Rust installer), not system packages
  • Installs stable toolchain by default
  • Installed in user's home directory (~/.cargo/)
  • Note: Windows cross-compilation target (x86_64-pc-windows-gnu) is automatically added in Phase 4 during InfiniService build (via rustup target add)

Verification:

  • Checks that all required commands exist: node, npm, psql, qemu-system-x86_64, rustc, cargo
  • Enforces Node.js version β‰₯18 (fails installation if lower)
  • Confirms mingw-w64 toolchain is available (x86_64-w64-mingw32-gcc)
  • Tests KVM support (/dev/kvm exists and is accessible)

Source: file:installer/lib/system_check.py (lines 500-580)


Phase 3: Database Setup

Purpose: Create and configure PostgreSQL database for Infinibay.

What it does:

  1. Tests PostgreSQL service connectivity (as postgres superuser)
  2. Creates database user with password and CREATEDB privilege
  3. Creates infinibay database owned by the user
  4. Configures pg_hba.conf for password authentication (if needed)
  5. Tests connection with new user credentials
  6. Verifies user has necessary permissions (CREATE TABLE, etc.)

SQL executed:

-- Create user with password
CREATE USER infinibay WITH PASSWORD 'generated_password' CREATEDB NOSUPERUSER INHERIT NOCREATEROLE;

-- Create database
CREATE DATABASE infinibay OWNER infinibay;

-- Grant privileges (automatic via OWNER)
GRANT ALL PRIVILEGES ON DATABASE infinibay TO infinibay;

Authentication configuration:

  • Checks pg_hba.conf for password authentication (md5 or scram-sha-256)
  • Ubuntu location: /etc/postgresql/*/main/pg_hba.conf
  • Fedora location: /var/lib/pgsql/data/pg_hba.conf
  • Recommends adding: local all all md5 for local password auth

Interactive troubleshooting: If database connection fails, the installer provides step-by-step guidance:

  1. Check PostgreSQL service status
  2. Create user manually via psql
  3. Configure pg_hba.conf for password authentication
  4. Reload PostgreSQL service
  5. Test connection again

Connection retries:

  • Maximum 3 connection attempts with 3-second delays
  • If all attempts fail, enters interactive troubleshooting mode
  • User can fix issues and retry without restarting installer

Source: file:installer/lib/database.py (lines 422-532)


Phase 4: Repository Setup

Purpose: Clone repositories and build all components in the correct order.

What it does:

  1. Clones 4 repositories from GitHub to installation directory
  2. Builds dependencies in specific order (order is critical!)
  3. Cross-compiles InfiniService for Linux and Windows
  4. Deploys InfiniService binaries to backend
  5. Verifies all builds completed successfully

Repositories cloned:

Repository URL Purpose
backend https://github.com/infinibay/backend.git GraphQL API server (Node.js + Apollo Server)
infinization https://github.com/infinibay/infinization.git TypeScript QEMU command builder
frontend https://github.com/infinibay/frontend.git Next.js web interface
infiniservice https://github.com/infinibay/infiniservice.git Rust guest agent (runs inside VMs)

Build order (critical!):

1. backend       β†’ Generates Prisma client, creates base types
2. infinization  β†’ Depends on backend types, npm creates symlink
3. frontend      β†’ Uses GraphQL schema from backend for codegen
4. infiniservice β†’ Independent Rust project, builds last

Why build order matters:

  • Backend first: Generates Prisma client (@prisma/client) needed by other components
  • Infinization second: TypeScript compilation depends on backend types; npm automatically creates symlink to backend
  • Frontend third: GraphQL code generation (npm run codegen) requires backend schema
  • InfiniService last: Independent Rust project with no dependencies on other components

Build commands executed:

Backend

cd /opt/infinibay/backend
npm install              # Install dependencies
npx prisma generate      # Generate Prisma client

Infinization

cd /opt/infinibay/infinization
npm install              # Install deps + create symlink to backend
npm run build            # Compile TypeScript to JavaScript

Frontend

cd /opt/infinibay/frontend
npm install              # Install dependencies
npm run codegen          # Generate GraphQL hooks from schema
npm run build            # Build Next.js production bundle

InfiniService (Cross-Compilation)

cd /opt/infinibay/infiniservice

# Automatically add Windows cross-compilation target (idempotent - safe if already installed)
rustup target add x86_64-pc-windows-gnu

# Build for Linux (native)
cargo build --release

# Build for Windows (cross-compilation via mingw-w64)
cargo build --release --target x86_64-pc-windows-gnu

Note: The installer automatically runs rustup target add x86_64-pc-windows-gnu before the Windows build. This is idempotentβ€”it succeeds whether the target is already installed or not.

InfiniService binaries:

  • Linux: target/release/infiniservice (native ELF binary)
  • Windows: target/x86_64-pc-windows-gnu/release/infiniservice.exe (PE32+ executable)
  • Both binaries are deployed to backend/infiniservice/ for serving to VMs

Development mode:

  • If --install-dir points to existing workspace with .git directories, skips cloning
  • Builds in place without cloning
  • Preserves file ownership (restores to original user after builds)

Source: file:installer/lib/repos.py (lines 890-1133)


Phase 5: Configuration & Services

Purpose: Generate configuration files, run migrations, and start services.

What it does:

  1. Creates data directories (iso/, disks/, sockets/, wallpapers/)
  2. Creates infinization directories (/var/lib/infinization/)
  3. Generates backend .env file with all configuration
  4. Generates frontend .env file with backend URLs
  5. Runs Prisma database migrations (npx prisma migrate deploy)
  6. Executes backend setup script (npm run setup)
  7. Creates systemd service files for backend and frontend
  8. Enables and starts both services
  9. Displays installation summary with URLs and credentials

Backend .env configuration:

DATABASE_URL="postgresql://infinibay:password@localhost:5432/infinibay"
FRONTEND_URL="*"
TOKENKEY="<generated-32-byte-secret>"
PORT=4000
BCRYPT_ROUNDS=10
DEFAULT_ADMIN_EMAIL="admin@example.com"
DEFAULT_ADMIN_PASSWORD="password"
RPC_URL="http://localhost:9090"
APP_HOST=192.168.1.100
INFINIBAY_BASE_DIR=/opt/infinibay
INFINIBAY_ISO_DIR=/opt/infinibay/iso
INFINIBAY_ISO_TEMP_DIR=/opt/infinibay/iso/temp
INFINIBAY_ISO_PERMANENT_DIR=/opt/infinibay/iso/permanent
INFINIBAY_WALLPAPERS_DIR=/opt/infinibay/wallpapers
GRAPHIC_HOST=192.168.1.100

Frontend .env configuration:

NEXT_PUBLIC_BACKEND_HOST=http://192.168.1.100:4000
NEXT_PUBLIC_GRAPHQL_API_URL=http://192.168.1.100:4000/graphql

Backend setup script (npm run setup):

  • Creates directory structure (ISO, disks, sockets, wallpapers)
  • Configures nftables firewall rules for VM networking
  • Seeds database with initial data (admin user, default settings)
  • Downloads Ubuntu/Fedora ISOs (unless --skip-isos flag used)
  • Downloads Windows ISOs (unless --skip-windows-isos flag used)

Systemd services created:

  • infinibay-backend.service: Backend GraphQL API server
  • infinibay-frontend.service: Frontend Next.js web server

Service configuration:

  • Run as root (required for /dev/kvm access and network configuration)
  • Auto-restart on failure (Restart=always, RestartSec=10)
  • Start on boot (WantedBy=multi-user.target)
  • Depend on PostgreSQL (After=postgresql.service, Requires=postgresql.service)

Service startup:

  • Executes systemctl daemon-reload to recognize new services
  • Enables services: systemctl enable infinibay-backend infinibay-frontend
  • Starts services: systemctl start infinibay-backend infinibay-frontend
  • Waits up to 30 seconds for services to activate
  • Verifies services are running: systemctl is-active <service>

Source: file:installer/lib/services.py (lines 626-863)


Installation Flow Diagram

graph TD
    A[Start Installation] --> B[Phase 1: Framework Init]
    B --> C[Phase 2: System Dependencies]
    C --> D[Phase 3: Database Setup]
    D --> E[Phase 4: Repository Setup]
    E --> F[Phase 5: Configuration & Services]
    F --> G[Installation Complete]

    B --> B1[Detect OS Version]
    B --> B2[Check Root Privileges]
    B --> B3[Detect Host IP]
    B --> B4[Generate DB Password]
    B --> B5[Prompt Admin Credentials]

    C --> C1[Update Package Cache]
    C --> C2[Enforce Node.js 18+]
    C --> C3[Install PostgreSQL]
    C --> C4[Install QEMU/KVM]
    C --> C5[Install Rust via rustup]
    C --> C6[Install mingw-w64]
    C --> C7[Verify Installations]

    D --> D1[Test PostgreSQL Service]
    D --> D2[Create DB User]
    D --> D3[Create Database]
    D --> D4[Configure pg_hba.conf]
    D --> D5[Verify Permissions]

    E --> E1[Clone Repositories]
    E --> E2[Build Backend]
    E --> E3[Build Infinization]
    E --> E4[Build Frontend]
    E --> E5[Build InfiniService]
    E --> E6[Deploy Binaries]

    F --> F1[Create Data Directories]
    F --> F2[Generate .env Files]
    F --> F3[Run Migrations]
    F --> F4[Backend Setup Script]
    F --> F5[Create Systemd Services]
    F --> F6[Start Services]

    style B fill:#e1f5ff
    style C fill:#fff4e1
    style D fill:#e8f5e9
    style E fill:#f3e5f5
    style F fill:#fce4ec
    style G fill:#c8e6c9

Automated vs Manual Installation Comparison

Aspect Automated Installer Manual Installation
Time Required 20-40 minutes 60-90 minutes
Complexity Low - single command High - multiple steps
Error Handling Automatic retries, interactive troubleshooting Manual debugging required
Customization Limited to CLI flags Full control over every step
Learning Value Low - black box High - understand system architecture
Repeatability High - idempotent Medium - manual errors possible
Troubleshooting Requires reading logs Easy - see each command
Best For Production, testing, quick setup Development, custom configs, learning
Prerequisites Python 3.8+, sudo access Same + understanding of each component
Rollback Uninstall script provided Manual cleanup required

Source Code References

For advanced users who want to understand the installer internals:

File Purpose Key Functions
file:installer/install.py Main orchestrator main(), display_installation_summary()
file:installer/lib/args.py CLI argument parsing parse_arguments()
file:installer/lib/config.py Configuration context InstallerContext, create_context_from_args()
file:installer/lib/os_detect.py OS detection and validation detect_os(), validate_os_version()
file:installer/lib/system_check.py Phase 2 implementation run_system_checks(), install_packages()
file:installer/lib/database.py Phase 3 implementation setup_database(), interactive_troubleshooting_guide()
file:installer/lib/repos.py Phase 4 implementation clone_and_build(), build_backend(), build_infiniservice()
file:installer/lib/services.py Phase 5 implementation create_services(), generate_backend_env()
file:installer/lib/utils.py Utility functions run_command(), command_exists()
file:installer/lib/logger.py Logging and output log_step(), log_success(), log_error()

Important Implementation Notes

  1. Build order is critical: Backend β†’ Infinization β†’ Frontend β†’ InfiniService. Changing this order will cause build failures.

  2. Services run as root: Required for:

    • /dev/kvm access (hardware virtualization)
    • nftables firewall configuration
    • Network bridge management
  3. Infinization uses nftables: VM networking is managed via nftables, not libvirt networking. Libvirt is not installed.

  4. Cross-compilation: InfiniService builds for both Linux and Windows using mingw-w64 toolchain. Windows binary is served to Windows VMs via backend.

  5. Password encoding: Database passwords with special characters are URL-encoded in DATABASE_URL for Prisma compatibility.

  6. Development mode: If --install-dir points to existing workspace, installer skips cloning and builds in place, preserving file ownership.

  7. Dry-run mode: Use --dry-run flag to see what would be done without making changes.

  8. Verbose logging: Use --verbose flag for detailed command output and debugging information.


What Happens After Installation

Once installation completes:

  1. Services are running:

    • Backend: http://<host-ip>:4000 (GraphQL API)
    • Frontend: http://<host-ip>:3000 (Web UI)
  2. Database is ready:

    • Migrations applied
    • Admin user created
    • Default settings configured
  3. VM infrastructure ready:

    • QEMU/KVM available
    • Infinization directories created
    • nftables firewall configured
    • ISOs downloaded (unless skipped)
  4. Next steps:

    • Access web UI at http://<host-ip>:3000
    • Log in with admin credentials
    • Change default password
    • Create departments and configure firewall rules
    • Create your first virtual machine

Troubleshooting Installation Issues

If installation fails at any phase:

Phase 1 failures:

  • Unsupported OS version β†’ Upgrade to Ubuntu 23.10+ or Fedora 37+
  • Permission denied β†’ Run with sudo python3 install.py

Phase 2 failures:

  • Package installation timeout β†’ Check internet connection, retry
  • KVM not available β†’ Enable virtualization in BIOS/UEFI

Phase 3 failures:

  • PostgreSQL connection failed β†’ Follow interactive troubleshooting guide
  • Authentication failed β†’ Configure pg_hba.conf for password auth

Phase 4 failures:

  • Git clone failed β†’ Check GitHub access, use SSH keys or personal access token
  • Build failed β†’ Check disk space, verify Node.js/Rust versions
  • npm checksum error β†’ Installer cleans cache automatically, retry

Phase 5 failures:

  • Migration failed β†’ Verify database connection, check DATABASE_URL
  • Service failed to start β†’ Check logs with journalctl -u infinibay-backend -n 50

General troubleshooting:

  • Run with --verbose for detailed output
  • Check logs: journalctl -u infinibay-backend -f
  • Verify services: systemctl status infinibay-backend infinibay-frontend
  • Test database: psql -h localhost -U infinibay -d infinibay

Network Configuration

Automatic Network Detection

The installer detects and configures libvirt networks automatically. Prefers default network, or creates infinibay NAT network if none exist.

Network Modes

  • NAT (default): VMs use private IPs, access internet via host
  • Bridged: VMs get IPs from physical network, visible to other hosts
  • Isolated: VMs can only talk to host, no internet

Custom Network Setup

# List available networks
virsh net-list --all

# Use specific network
sudo python3 install.py --libvirt-network-name=your-network

Command-Line Reference

Complete reference of all installation options. Defaults shown below are subject to change; the installer output is the source of truth.

Database Configuration

Option Default Description Example
--db-password auto-generated PostgreSQL password for infinibay user --db-password=SecurePass123
--db-user infinibay PostgreSQL username --db-user=infinibay_prod
--db-host localhost PostgreSQL host --db-host=192.168.1.50
--db-port 5432 PostgreSQL port --db-port=5433
--db-name infinibay PostgreSQL database name --db-name=infinibay_prod

Admin User Configuration

Option Default Description Example
--admin-email admin@example.com Admin user email address --admin-email=admin@infinibay.local
--admin-password password Admin user password --admin-password=Admin2024!

Network Configuration

Option Default Description Example
--host-ip auto-detected Host IP address for VMs to connect --host-ip=192.168.1.100
--libvirt-network-name default Libvirt network name --libvirt-network-name=br0
--backend-port 4000 Backend GraphQL server port --backend-port=8080
--frontend-port 3000 Frontend web server port --frontend-port=8081

Installation Paths

Option Default Description Example
--install-dir /opt/infinibay Installation directory (must be absolute) --install-dir=/opt/custom/path
--data-dir same as install-dir Data directory for ISOs, disks, etc. --data-dir=/mnt/storage/infinibay

Repository Options

Option Default Description Example
--use-local-repos false Use local repository code instead of cloning --use-local-repos
--local-repos-dir - Path to local repositories directory --local-repos-dir=/home/user/infinibay

Installation Options

Option Default Description Example
--skip-isos false Skip downloading Ubuntu/Fedora ISOs --skip-isos
--skip-windows-isos false Skip downloading Windows ISOs --skip-windows-isos

Execution Modes

Option Default Description Example
--dry-run false Show what would be done without executing --dry-run
--verbose false Enable verbose logging --verbose

Version Information

Option Description Example Output
--version Show installer version and exit Infinibay Installer v1.0.0
# Check installer version
python3 install.py --version
# Output: Infinibay Installer v1.0.0

Usage Examples

# Basic installation
sudo python3 install.py

# Custom password
sudo python3 install.py --db-password=SecurePass2024!

# Custom network
sudo python3 install.py --host-ip=192.168.1.100 --libvirt-network-name=br0

# Development mode (from workspace root)
sudo python3 installer/install.py --install-dir=/home/andres/infinibay

Troubleshooting Common Issues

Permission Denied

Run with sudo:

sudo python3 install.py

Unsupported OS Version

Requires Ubuntu 23.10+ or Fedora 37+. Upgrade your OS.

Database Connection Failed

Check service status and pg_hba.conf authentication. The installer provides interactive troubleshooting if connection fails.

Invalid Port Number in Database URL

The installer URL-encodes passwords automatically. If you still see errors, use a simple password without special characters.

GitHub Authentication Required

Generate a personal access token at https://github.com/settings/tokens with repo scope. Use it as your password when Git prompts for credentials. Or use SSH keys.

Build Failures

Check internet connectivity and disk space. Run with --verbose for details.

libvirt-node Integrity Checksum Error

The installer cleans npm cache automatically. If you still see checksum errors:

cd /opt/infinibay/backend
npm cache clean --force
rm package-lock.json
npm install

Port Already in Use

Use --backend-port and --frontend-port to avoid conflicts. Check with lsof -i :3000.

Network Bridge Issues

Check libvirt network status with virsh net-list --all. Start default network if inactive.

Post-Installation Verification

Check service status:

systemctl status infinibay-backend infinibay-frontend

Access web interface at http://<your-host-ip>:3000 and GraphQL playground at http://<your-host-ip>:4000/graphql.

Check logs:

journalctl -u infinibay-backend -f
journalctl -u infinibay-frontend -f

Service Management

# Start/stop/restart
sudo systemctl start infinibay-backend infinibay-frontend
sudo systemctl stop infinibay-backend infinibay-frontend
sudo systemctl restart infinibay-backend infinibay-frontend

# Check status
sudo systemctl status infinibay-backend infinibay-frontend

# View logs
sudo journalctl -u infinibay-backend -f

# Enable/disable autostart
sudo systemctl enable infinibay-backend infinibay-frontend
sudo systemctl disable infinibay-backend infinibay-frontend

# Reload configuration after editing service files
sudo systemctl daemon-reload
sudo systemctl restart infinibay-backend infinibay-frontend

Uninstallation

Run from the installer repo or use the full path to uninstall.py:

cd ~/installer  # or wherever you cloned the installer
Command Removes Keeps
sudo python3 uninstall.py Services only Files, Database
sudo python3 uninstall.py --remove-files Services + Files Database
sudo python3 uninstall.py --remove-database Services + Database Files
sudo python3 uninstall.py --remove-files --remove-database Everything Nothing

Additional flags: --dry-run, --yes, --verbose, --install-dir, --db-name, --db-user

Manual Installation Guide

This section provides step-by-step instructions for manually installing Infinibay without using the automated installer. Manual installation gives you full control over each step and is useful for:

  • Development environments: Customize build options and debug configurations
  • Custom configurations: Non-standard paths, ports, or database setups
  • Troubleshooting: Understand what the installer does to diagnose issues
  • Learning: Understand system architecture and component relationships

Prerequisites

Before starting manual installation, ensure you have:

  • Operating System: Ubuntu 23.10+ or Fedora 37+
  • Root/sudo access: Required for system package installation and service creation
  • Disk space: Minimum 10GB free in /opt (or your chosen installation directory)
  • Internet connectivity: Required for downloading packages and cloning repositories
  • Hardware virtualization: CPU with Intel VT-x or AMD-V enabled

Verify hardware virtualization support:

egrep -c '(vmx|svm)' /proc/cpuinfo
# Should return > 0

Phase 1: Install System Dependencies

Ubuntu/Debian

# Update package cache
sudo apt update

# Install Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

# Install PostgreSQL
sudo apt install -y postgresql postgresql-contrib

# Install QEMU/KVM
sudo apt install -y qemu-kvm bridge-utils cpu-checker

# Install build tools and dependencies
sudo apt install -y build-essential pkg-config libssl-dev mingw-w64 btrfs-progs p7zip-full curl

Fedora

# Update package cache
sudo dnf update -y

# Install Node.js 18+
sudo dnf install -y nodejs npm

# Install PostgreSQL
sudo dnf install -y postgresql postgresql-server

# Install QEMU/KVM
sudo dnf install -y qemu-kvm bridge-utils

# Install build tools and dependencies
sudo dnf install -y gcc gcc-c++ make pkg-config openssl-devel mingw64-gcc btrfs-progs p7zip curl

Install Rust (Both OS)

# Install Rust via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable

# Load Rust environment
source $HOME/.cargo/env

# Verify installation
rustc --version
cargo --version

# Add Windows cross-compilation target (for InfiniService)
rustup target add x86_64-pc-windows-gnu

Phase 2: Configure PostgreSQL

Initialize PostgreSQL (Fedora only)

# Initialize database cluster (Fedora only)
sudo postgresql-setup --initdb

Start PostgreSQL Service

# Start and enable PostgreSQL
sudo systemctl start postgresql
sudo systemctl enable postgresql

# Verify it's running
sudo systemctl status postgresql

Create Database and User

# Create infinibay user and database
sudo -u postgres psql <<EOF
CREATE USER infinibay WITH PASSWORD 'your_secure_password' CREATEDB;
CREATE DATABASE infinibay OWNER infinibay;
GRANT ALL PRIVILEGES ON DATABASE infinibay TO infinibay;
\q
EOF

Configure Authentication

Edit pg_hba.conf to allow password authentication:

  • Ubuntu: /etc/postgresql/*/main/pg_hba.conf
  • Fedora: /var/lib/pgsql/data/pg_hba.conf

Add or modify these lines (before any peer or ident rules):

# IPv4 local connections:
local   all             all                                     md5
host    all             all             127.0.0.1/32            md5
host    all             all             ::1/128                 md5

Reload PostgreSQL to apply changes:

sudo systemctl reload postgresql

Verify connection:

psql -U infinibay -d infinibay -h localhost -c "SELECT 1;"
# Should prompt for password and return "1"

Phase 3: Clone Repositories

# Create installation directory
sudo mkdir -p /opt/infinibay
sudo chown $USER:$USER /opt/infinibay
cd /opt/infinibay

# Clone repositories in order
git clone https://github.com/infinibay/backend.git
git clone https://github.com/infinibay/infinization.git
git clone https://github.com/infinibay/frontend.git
git clone https://github.com/infinibay/infiniservice.git

Phase 4: Build Dependencies (Order Critical)

Why build order matters:

  • Backend first: Generates Prisma client needed by other components
  • Infinization second: Depends on backend types; npm creates symlink automatically
  • Frontend third: Needs GraphQL schema from backend for code generation
  • InfiniService last: Independent Rust project, can build anytime

1. Build Backend

cd /opt/infinibay/backend

# Install dependencies
npm install

# Generate Prisma client (required before running)
npx prisma generate

2. Build Infinization

cd /opt/infinibay/infinization

# Install dependencies (creates symlink to backend automatically)
npm install

# Build TypeScript
npm run build

3. Build Frontend

cd /opt/infinibay/frontend

# Install dependencies
npm install

# Generate GraphQL hooks from schema
npm run codegen

# Build for production
npm run build

4. Build InfiniService (Cross-Compilation)

cd /opt/infinibay/infiniservice

# Build for Linux
cargo build --release

# Build for Windows (cross-compilation)
cargo build --release --target x86_64-pc-windows-gnu

Binaries are generated in:

  • Linux: target/release/infiniservice
  • Windows: target/x86_64-pc-windows-gnu/release/infiniservice.exe

Phase 5: Configure Environment Variables

Backend .env

Create /opt/infinibay/backend/.env:

cat > /opt/infinibay/backend/.env <<EOF
# Database Configuration
DATABASE_URL="postgresql://infinibay:your_secure_password@localhost:5432/infinibay"

# CORS Configuration
FRONTEND_URL="*"

# JWT Secret (generate unique key)
TOKENKEY="$(openssl rand -base64 32)"

# Server Configuration
PORT=4000

# Security Settings
BCRYPT_ROUNDS=10

# Default Admin User
DEFAULT_ADMIN_EMAIL="admin@example.com"
DEFAULT_ADMIN_PASSWORD="password"

# InfiniService RPC
RPC_URL="http://localhost:9090"

# Application Configuration (replace with your host IP)
APP_HOST=192.168.1.100
INFINIBAY_BASE_DIR=/opt/infinibay
INFINIBAY_ISO_DIR=/opt/infinibay/iso
INFINIBAY_ISO_TEMP_DIR=/opt/infinibay/iso/temp
INFINIBAY_ISO_PERMANENT_DIR=/opt/infinibay/iso/permanent
INFINIBAY_WALLPAPERS_DIR=/opt/infinibay/wallpapers

# Graphics Configuration (replace with your host IP)
GRAPHIC_HOST=192.168.1.100
EOF

# Secure the file
chmod 600 /opt/infinibay/backend/.env

Frontend .env

Create /opt/infinibay/frontend/.env:

cat > /opt/infinibay/frontend/.env <<EOF
# Backend API URLs (replace with your host IP)
NEXT_PUBLIC_BACKEND_HOST=http://192.168.1.100:4000
NEXT_PUBLIC_GRAPHQL_API_URL=http://192.168.1.100:4000/graphql
EOF

chmod 644 /opt/infinibay/frontend/.env

Phase 6: Create Infinization Directories

Infinization stores VM disks, UNIX sockets, and PID files in /var/lib/infinization/:

# Create directory structure
sudo mkdir -p /var/lib/infinization/{disks,sockets,pids}

# Set permissions
sudo chmod 755 /var/lib/infinization
sudo chmod 755 /var/lib/infinization/{disks,sockets,pids}

Phase 7: Run Database Migrations

cd /opt/infinibay/backend

# Apply database migrations
npx prisma migrate deploy

# Run backend setup (creates folders, configures nftables, seeds database)
npm run setup

The setup script:

  • Creates ISO directories
  • Configures nftables for VM networking
  • Seeds initial data (admin user, default settings)

Phase 8: Create Systemd Services

Backend Service

Create /etc/systemd/system/infinibay-backend.service:

sudo tee /etc/systemd/system/infinibay-backend.service > /dev/null <<EOF
[Unit]
Description=Infinibay Backend API Server
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/infinibay/backend
ExecStart=/usr/bin/npm run start
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
Environment="NODE_ENV=production"
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

[Install]
WantedBy=multi-user.target
EOF

Frontend Service

Create /etc/systemd/system/infinibay-frontend.service:

sudo tee /etc/systemd/system/infinibay-frontend.service > /dev/null <<EOF
[Unit]
Description=Infinibay Frontend Web Interface
After=network.target infinibay-backend.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/infinibay/frontend
ExecStart=/usr/bin/npm run start
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
Environment="NODE_ENV=production"
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

[Install]
WantedBy=multi-user.target
EOF

Phase 9: Start Services

# Reload systemd to recognize new services
sudo systemctl daemon-reload

# Enable services (start on boot)
sudo systemctl enable infinibay-backend infinibay-frontend

# Start services
sudo systemctl start infinibay-backend infinibay-frontend

# Verify status
sudo systemctl status infinibay-backend infinibay-frontend

Phase 10: Verify Installation

# Check backend health
curl http://localhost:4000/health

# Check frontend (should return HTML)
curl -s http://localhost:3000 | head -20

# View backend logs
sudo journalctl -u infinibay-backend -f

# View frontend logs
sudo journalctl -u infinibay-frontend -f

Access the web interface at http://<your-host-ip>:3000 and log in with:

What the Automated Installer Does

The automated installer (install.py) performs all the steps above automatically across five phases. Understanding what it does helps with troubleshooting and customization.

Installation Flow Diagram

graph TD
    A[Start Installation] --> B[Phase 1: Framework Init]
    B --> C[Phase 2: System Dependencies]
    C --> D[Phase 3: Database Setup]
    D --> E[Phase 4: Clone & Build Repos]
    E --> F[Phase 5: Configuration & Services]
    F --> G[Installation Complete]

    B --> B1[Validate OS Version]
    B --> B2[Detect Host IP]
    B --> B3[Generate DB Password]

    C --> C1[Install Node.js, PostgreSQL]
    C --> C2[Install QEMU/KVM, libvirt]
    C --> C3[Install Rust + mingw-w64]

    D --> D1[Create DB User]
    D --> D2[Create Database]
    D --> D3[Configure pg_hba.conf]

    E --> E1[Clone Repositories]
    E --> E2[Build Backend]
    E --> E3[Build Infinization]
    E --> E4[Build Frontend]
    E --> E5[Build InfiniService]

    F --> F1[Generate .env Files]
    F --> F2[Run Migrations]
    F --> F3[Backend Setup Script]
    F --> F4[Create Systemd Services]
    F --> F5[Start Services]

Phase-by-Phase Breakdown

Phase Purpose Key Actions
1. Framework Init Validate environment Check OS version, detect IP, generate passwords
2. Dependencies Install system packages Node.js, PostgreSQL, QEMU/KVM, Rust, build tools
3. Database Configure PostgreSQL Create user/database, configure authentication
4. Repositories Build all components Clone repos, build in correct order (backend β†’ infinization β†’ frontend β†’ infiniservice)
5. Services Configure and start Generate .env files, run migrations, create systemd services

Automated vs Manual Installation

Aspect Manual Installation Automated Installer
Time 30-60 minutes 10-20 minutes
Control Full control over every step Limited to command-line flags
Troubleshooting Easy - you see each command Requires reading logs
Learning High - understand the system Low - black box
Customization Any configuration possible Predefined options only
Repeatability Manual, error-prone Consistent, idempotent
Best for Development, custom configs, learning Production, testing, quick setup

Source Code References

For advanced users, here are the installer source files:

File Purpose
installer/install.py Main orchestrator, runs all phases
installer/lib/system_check.py OS detection, package installation
installer/lib/database.py PostgreSQL configuration
installer/lib/repos.py Repository cloning and building
installer/lib/services.py Environment files, systemd services

Important Notes

  1. Replace IP addresses: Change 192.168.1.100 to your actual host IP throughout
  2. Secure passwords: Replace your_secure_password with a strong password
  3. Build order is critical: Backend β†’ Infinization β†’ Frontend β†’ InfiniService
  4. Services run as root: Required for /dev/kvm access and network configuration
  5. Infinization uses nftables: VM networking managed via nftables, not libvirt networking
  6. Cross-compilation: InfiniService builds for both Linux and Windows using mingw-w64

Next Steps

  1. Access http://<your-host-ip>:3000
  2. Log in with admin@example.com / password
  3. Change admin password in Settings β†’ Account
  4. Create departments and configure firewall rules
  5. Navigate to VMs β†’ Create VM

Documentation:

Upgrading to LXD Deployment

Once LXD container deployment becomes available, you can migrate your existing installation:

  1. Export data: Backup VMs, database, and configuration
  2. Deploy LXD container: Use lxd-compose up or lxc launch infinibay
  3. Import data: Restore backup into container
  4. Uninstall direct: Remove host installation with uninstall.py --remove-files

LXD deployment will be documented separately when released.

Additional Resources