FreeBSD-Up 🚀#
A comprehensive FreeBSD virtual machine management tool built with Deno and QEMU. Effortlessly create, manage, and run FreeBSD VMs with persistent state tracking, network bridging support, and zero-configuration defaults.
✨ Features#
Core VM Management#
- 🏗️ Full VM lifecycle management: Create, start, stop, restart, inspect, and remove VMs
- 💾 Persistent state tracking: SQLite database stores VM configurations and state
- 📊 VM listing and monitoring: View running and stopped VMs with detailed information
- 🔍 VM inspection: Get detailed information about any managed VM
- 📋 VM logging: View and follow VM logs with built-in log management
- 🔄 VM restart: Gracefully restart VMs with preserved configuration
- 🗑️ VM removal: Clean removal of VMs from the database
- 🏷️ Auto-generated VM names: Unique identifiers for easy VM management
- 🏛️ Cross-platform support: Works on both x86_64 and aarch64 architectures
- 🔧 Background mode: Run VMs in detached mode for headless operation
- 🚀 Run from images: Create and run VMs directly from OCI registry images
- 💾 Install mode: Persist changes to VM disk images with
--installflag
Network & Storage#
- 🌐 Flexible networking: Support for both user-mode and bridge networking
- 🔗 Network bridge support: Automatic bridge creation and management with
--bridge - 🖧 MAC address management: Persistent MAC addresses for each VM
- 📍 Port forwarding: Custom port mapping for network services with
--port-forward - 💾 Persistent storage support: Attach and auto-create disk images
- 🗂️ Multiple disk formats: Support for qcow2, raw, and other disk formats
- 📏 Configurable disk sizes: Specify disk image size on creation
- 🗄️ Volume management: Create, list, inspect, and remove persistent volumes
- 🔗 Volume attachment: Attach volumes to VMs with
--volumeflag
Convenience Features#
Image Management & OCI Registry Support#
- 📦 OCI Registry Integration: Pull and push VM disk images to OCI-compatible registries
- 🗂️ Image Management: List, tag, and remove VM disk images with
images,tag, andrmicommands - 🔐 Registry Authentication: Login and logout from OCI registries with
loginandlogoutcommands - 🔄 Image Sharing: Share VM configurations and disk images across teams and environments
- 📥 Pull from Registry: Download pre-configured VM images from remote registries
- 📤 Push to Registry: Upload VM disk images to remote registries for distribution
Configuration Management#
- 📄 Configuration Files: Support for TOML-based VM configuration files with
vmconfig.toml - ⚙️ Declarative VM Setup: Define VM settings in configuration files for reproducible environments
- 🔧 Init Command: Generate default configuration files with
freebsd-up init - 🔀 Config Merging: Command-line options override configuration file settings
HTTP API Server#
-
🌐 RESTful API: Built-in HTTP API server for remote VM management
-
🔐 Bearer Token Authentication: Secure API access with token authentication
-
🖥️ Machine Management API: Create, start, stop, and manage VMs via HTTP
-
🗂️ Image Management API: List, pull, push, and manage VM images via HTTP
-
💾 Volume Management API: Create, list, inspect, and remove volumes via HTTP
-
🔧 Configurable Port: Customize API server port with
--portor environment variable -
📊 CORS Support: Built-in CORS support for web-based clients
-
🔗 Download and boot from URLs: Automatically downloads ISO images from remote URLs
-
📁 Local file support: Boot from local ISO files
-
🏷️ Version shortcuts: Simply specify a version like
14.3-RELEASEto auto-download -
🎯 Smart defaults: Run without arguments to boot the latest stable release (FreeBSD 14.3-RELEASE)
-
⚡ Zero configuration: Works out of the box with sensible defaults
-
🖥️ Serial console: Configured for headless operation with stdio console
-
💾 Smart caching: Automatically skips re-downloading existing ISO files
-
🆘 Help support: Built-in help with
--helpor-hflags -
⚙️ Configurable VM options: Customize CPU type, core count, memory allocation
-
📝 Enhanced CLI: Powered by Cliffy for robust command-line parsing
📋 Prerequisites#
Before using FreeBSD-Up, make sure you have:
- Deno - Modern JavaScript/TypeScript runtime
- QEMU - Hardware virtualization
- KVM support (Linux) - For hardware acceleration (optional but recommended)
Installation on Common Systems#
Ubuntu/Debian:
sudo apt-get update
sudo apt-get install qemu-system-x86 qemu-kvm
curl -fsSL https://deno.land/install.sh | sh
Fedora:
sudo dnf install qemu qemu-kvm
curl -fsSL https://deno.land/install.sh | sh
macOS:
brew install qemu deno
Run the following command to install the CLI:
deno install -A -g -r -f jsr:@tsiry/freebsd-up
🚀 Quick Start#
Default Usage (Easiest)#
Simply run without any arguments to boot the latest stable FreeBSD release:
freebsd-up
This will automatically download and boot FreeBSD 14.3-RELEASE.
Boot with Version Shortcut#
Specify just a version to auto-download and boot:
freebsd-up 14.3-RELEASE
freebsd-up 15.0-BETA3
freebsd-up 13.4-RELEASE
Boot from URL#
Download and boot from a specific URL:
freebsd-up https://download.freebsd.org/ftp/releases/amd64/amd64/ISO-IMAGES/15.0/FreeBSD-15.0-BETA3-amd64-disc1.iso
Boot from Local File#
freebsd-up /path/to/your/freebsd.iso
VM Management Commands#
List all running VMs:
freebsd-up ps
List all VMs (including stopped):
freebsd-up ps --all
Start a specific VM:
freebsd-up start vm-name
Stop a specific VM:
freebsd-up stop vm-name
Inspect VM details:
freebsd-up inspect vm-name
Remove a VM:
freebsd-up rm vm-name
Restart a VM:
freebsd-up restart vm-name
View VM logs:
freebsd-up logs vm-name
Follow VM logs in real-time:
freebsd-up logs vm-name --follow
Image Management Commands#
List VM disk images:
freebsd-up images
Tag a VM disk image:
freebsd-up tag vm-name ghcr.io/tsirysndr/freebsd:15.0-BETA4
Remove a VM disk image:
freebsd-up rmi image-id
Login to OCI registry:
freebsd-up login -u tsirysndr ghcr.io
Logout from OCI registry:
freebsd-up logout ghcr.io
Pull an image from OCI registry:
freebsd-up pull ghcr.io/tsirysndr/freebsd:15.0-BETA4
Push an image to OCI registry:
freebsd-up push ghcr.io/tsirysndr/freebsd:15.0-BETA4
Run a VM from an OCI registry image:
freebsd-up run ghcr.io/tsirysndr/freebsd:15.0-BETA4
Volume Management Commands#
List all volumes:
freebsd-up volumes
Remove a volume:
freebsd-up volume rm volume-name
Inspect a volume:
freebsd-up volume inspect volume-name
Attach a volume to a VM:
freebsd-up start vm-name --volume my-volume
Starting the API Server#
Start the HTTP API server:
freebsd-up serve
Start the API server on a custom port:
freebsd-up serve --port 9000
Set a custom API token via environment variable:
export FREEBSD_UP_API_TOKEN=your-secret-token
freebsd-up serve
The API server provides RESTful endpoints for managing VMs, images, and volumes remotely. It includes bearer token authentication for security and supports CORS for web-based clients.
Using Configuration Files#
Initialize a configuration file in your project:
freebsd-up init
This creates a vmconfig.toml file with default settings. Example
configuration:
[vm]
iso = "https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/14.3/FreeBSD-14.3-RELEASE-amd64-disc1.iso"
cpu = "host"
cpus = 2
memory = "2G"
image = "./freebsd-disk.qcow2"
disk_format = "qcow2"
size = "20G"
[network]
bridge = "br0"
port_forward = "8080:80,2222:22"
[options]
detach = false
Command-line options will override configuration file settings, allowing you to customize VMs on a per-run basis while maintaining defaults in the config file.
Specify custom CPU type, core count, memory allocation, persistent storage, networking, and port forwarding:
# Custom CPU and memory
freebsd-up --cpu host --memory 4G 14.3-RELEASE
# Specify number of CPU cores
freebsd-up --cpus 4 --memory 8G 15.0-BETA3
# Attach a disk image for persistent storage
freebsd-up --image ./freebsd-disk.img --disk-format qcow2 14.3-RELEASE
# Create disk image with specific size
freebsd-up --image ./freebsd-disk.qcow2 --disk-format qcow2 --size 50G 14.3-RELEASE
# Use bridge networking (requires sudo)
freebsd-up --bridge br0 14.3-RELEASE
# Configure port forwarding for specific services
freebsd-up --port-forward 8080:80,2222:22 14.3-RELEASE
# Run VM in background (detached mode)
freebsd-up --detach 14.3-RELEASE
# Persist changes to disk (install mode)
freebsd-up --install 14.3-RELEASE
# Attach a volume to the VM
freebsd-up --volume my-data 14.3-RELEASE
# Download to specific location
freebsd-up --output ./downloads/freebsd.iso 15.0-BETA3
# Combine all options
freebsd-up --cpu qemu64 --cpus 2 --memory 1G --image ./my-disk.qcow2 --disk-format qcow2 --size 30G --bridge br0 --port-forward 8080:80,2222:22 --detach --volume my-data --install --output ./my-freebsd.iso
Get Help#
freebsd-up --help
# or
freebsd-up -h
Alternative Execution Methods#
If you haven't installed via deno install, you can run it directly with Deno:
deno run --allow-run --allow-read --allow-env -g -r -f main.ts -n freebsd-up
🔧 Command Line Options#
FreeBSD-Up supports several command-line options for customization:
VM Configuration Options#
-c, --cpu <type>- CPU type to emulate (default:host)-C, --cpus <number>- Number of CPU cores (default:2)-m, --memory <size>- Amount of memory for the VM (default:2G)-i, --image <path>- Path to VM disk image for persistent storage--disk-format <format>- Disk image format: qcow2, raw, etc. (default:raw)-s, --size <size>- Size of disk image to create if it doesn't exist (default:20G)
Network Options#
Network Options#
-b, --bridge <name>- Name of the network bridge to use (e.g., br0)-p, --port-forward <mappings>- Port forwarding rules in the format hostPort:guestPort (comma-separated for multiple)
Storage Options#
-v, --volume <name>- Name of the volume to attach to the VM (will be created if it doesn't exist)
Execution Options#
-d, --detach- Run VM in the background and print VM name--install- Persist changes to the VM disk image
File Options#
-o, --output <path>- Output path for downloaded ISO files
Management Commands#
init- Initialize a VM configuration file (vmconfig.toml) in the current directoryps [--all]- List running VMs (use --all to include stopped VMs)start <vm-name> [--detach] [-v, --volume <name>]- Start a specific VM by name (optionally in background, optionally attach a volume)stop <vm-name>- Stop a specific VM by namerestart <vm-name>- Restart a specific VM by nameinspect <vm-name>- Show detailed information about a VMlogs <vm-name> [--follow]- View VM logs (optionally follow in real-time)rm <vm-name>- Remove a VM and its configuration from the databaserun <image:tag> [options]- Create and run a VM from an OCI registry imageimages- List all VM disk imagestag <vm-name> <image:tag>- Tag a VM disk image for pushing to a registryrmi <image-id>- Remove a VM disk imagelogin -u <username> -p <password> <registry>- Login to an OCI registrylogout <registry>- Logout from an OCI registrypull <image:tag>- Pull a VM disk image from an OCI registrypush <image:tag>- Push a VM disk image to an OCI registryvolumes- List all volumesvolume rm <volume-name>- Remove a volumevolume inspect <volume-name>- Inspect a volumeserve [--port <port>]- Start the HTTP API server (default port: 8890)
Help Options#
-h, --help- Show help information-V, --version- Show version information
Examples#
# Use different CPU type
freebsd-up --cpu qemu64 14.3-RELEASE
# Allocate more memory
freebsd-up --memory 4G 15.0-BETA3
# Use more CPU cores
freebsd-up --cpus 4 14.3-RELEASE
# Attach a persistent disk image
freebsd-up --image ./freebsd-storage.qcow2 --disk-format qcow2 14.3-RELEASE
# Create a larger disk image automatically
freebsd-up --image ./freebsd-big.qcow2 --disk-format qcow2 --size 100G 14.3-RELEASE
# Use bridge networking for better network performance
freebsd-up --bridge br0 14.3-RELEASE
# Configure port forwarding for web and SSH access
freebsd-up --port-forward 8080:80,2222:22 14.3-RELEASE
# Run VM in background mode
freebsd-up --detach 14.3-RELEASE
# Persist changes to disk (install mode)
freebsd-up --install 14.3-RELEASE
# Attach a volume to the VM
freebsd-up --volume my-data 14.3-RELEASE
# Save ISO to specific location
freebsd-up --output ./isos/freebsd.iso https://example.com/freebsd.iso
# Combine multiple options with bridge networking, port forwarding, persistent storage, and volumes
freebsd-up --cpu host --cpus 4 --memory 8G --image ./vm-disk.qcow2 --disk-format qcow2 --size 50G --bridge br0 --port-forward 8080:80,2222:22 --detach --volume my-data --install --output ./downloads/ 14.3-RELEASE
# List all VMs (including stopped ones)
freebsd-up ps --all
# Start a previously created VM
freebsd-up start my-freebsd-vm
# Start a VM in background mode with volume
freebsd-up start my-freebsd-vm --detach --volume my-data
# Stop a running VM
freebsd-up stop my-freebsd-vm
# Restart a VM
freebsd-up restart my-freebsd-vm
# Get detailed information about a VM
freebsd-up inspect my-freebsd-vm
# View VM logs
freebsd-up logs my-freebsd-vm
# Follow VM logs in real-time
freebsd-up logs my-freebsd-vm --follow
# Remove a VM
freebsd-up rm my-freebsd-vm
# Run a VM from an OCI registry image
freebsd-up run ghcr.io/tsirysndr/freebsd:15.0-BETA4
# List all volumes
freebsd-up volumes
# Remove a volume
freebsd-up volume rm my-volume
# Inspect a volume
freebsd-up volume inspect my-volume
# Start the HTTP API server
freebsd-up serve
# Start API server on custom port
freebsd-up serve --port 9000
🖥️ Console Setup#
When FreeBSD boots, you'll see the boot menu. For the best experience with the serial console:
-
Select option
3. Escape to loader prompt -
Configure console output:
set console="comconsole"
boot
This enables proper console redirection to your terminal.
⚙️ VM Configuration#
The script creates a VM with the following default specifications:
- CPU: Host CPU with KVM acceleration (configurable with
--cpu) - Memory: 2GB RAM (configurable with
--memory) - Cores: 2 virtual CPUs (configurable with
--cpus) - Storage: ISO-only by default; optional persistent disk (configurable with
--image) - Network: User mode networking with SSH forwarding (host:2222 → guest:22)
or bridge networking with
--bridge - Port Forwarding: Configurable port mappings with
--port-forward - Console: Enhanced serial console via stdio with proper signal handling
- Default Version: FreeBSD 14.3-RELEASE (when no arguments provided)
- State Management: Persistent VM state stored in SQLite database
- Auto-naming: VMs get unique names for easy management
- Background Mode: Support for detached execution with
--detach
Networking Modes#
FreeBSD-Up supports two networking modes:
- User Mode (Default): Port forwarding for SSH access (host:2222 → guest:22)
- Bridge Mode: Direct network access via bridge interface (requires
--bridgeand sudo)
VM State Management#
All VMs are tracked in a local SQLite database with the following information:
- VM name and unique ID
- Hardware configuration (CPU, memory, cores)
- Network settings (bridge, MAC address)
- Storage configuration
- Current status (RUNNING, STOPPED)
- Process ID (when running)
- Creation timestamp
Available CPU Types#
Common CPU types you can specify with --cpu:
host(default) - Use host CPU features for best performanceqemu64- Generic 64-bit CPU for maximum compatibilityBroadwell- Intel Broadwell CPUSkylake-Client- Intel Skylake CPUmax- Enable all supported CPU features
Available Disk Formats#
Common disk formats you can specify with --disk-format:
raw(default) - Raw disk image format for maximum compatibilityqcow2- QEMU Copy On Write format with compression and snapshotsvmdk- VMware disk formatvdi- VirtualBox disk format
🔧 Customization#
Modifying VM Settings via Command Line#
The easiest way to customize VM settings is through command-line options:
# Increase memory to 4GB
freebsd-up --memory 4G
# Use a different CPU type
freebsd-up --cpu qemu64
# Increase CPU cores to 4
freebsd-up --cpus 4
# Add persistent storage
freebsd-up --image ./freebsd-data.qcow2 --disk-format qcow2 14.3-RELEASE
# Configure port forwarding for web server and SSH
freebsd-up --port-forward 8080:80,2222:22 14.3-RELEASE
# Run in background mode
freebsd-up --detach 14.3-RELEASE
# Combine options with persistent storage and port forwarding
freebsd-up --cpu host --cpus 4 --memory 8G --image ./vm-storage.qcow2 --disk-format qcow2 --port-forward 8080:80,2222:22 --detach 14.3-RELEASE
Creating Disk Images#
Before using the --image option, you may need to create a disk image.
FreeBSD-Up can automatically create disk images for you:
# Automatically create a 20GB qcow2 disk image (default size)
freebsd-up --image ./freebsd-data.qcow2 --disk-format qcow2 14.3-RELEASE
# Create a larger 50GB disk image
freebsd-up --image ./freebsd-large.qcow2 --disk-format qcow2 --size 50G 14.3-RELEASE
# Manually create disk images with qemu-img
qemu-img create -f qcow2 freebsd-data.qcow2 20G
qemu-img create -f raw freebsd-data.img 10G
Setting up Bridge Networking#
For bridge networking, you need to set up a bridge interface first:
# Create a bridge interface (requires root)
sudo ip link add br0 type bridge
sudo ip link set br0 up
# Add your network interface to the bridge
sudo ip link set eth0 master br0
# Then use FreeBSD-Up with bridge networking
freebsd-up --bridge br0 14.3-RELEASE
Note: Bridge networking requires sudo privileges and FreeBSD-Up will automatically create the bridge if it doesn't exist.
Advanced Customization#
To modify VM settings beyond command-line options, you can edit the QEMU
arguments in the relevant functions in src/utils.ts (for VM creation) or
src/subcommands/start.ts (for VM startup). The main.ts file serves as the CLI
entry point with subcommand routing.
Key architecture components:
- Modular design: Core functionality split into separate modules in
src/ - Database integration: SQLite database for persistent VM state management
(see
src/db.ts) - Image management: OCI registry integration for sharing and distributing VM
images (see
src/images.ts,src/oras.ts) - Volume management: Persistent volume support for VM storage (see
src/volumes.ts) - HTTP API: RESTful API server for remote VM management (see
src/api/) - Configuration files: TOML-based configuration for declarative VM setups
(see
src/config.ts) - Effect-based error handling: Functional error handling and async operations using the Effect library for robust error management
- Subcommand structure: Dedicated commands for VM lifecycle operations in
src/subcommands/ - Network management: Automatic bridge setup and MAC address assignment in
src/network.ts - State tracking: Comprehensive VM state persistence across restarts in
src/state.ts
Supported Version Formats#
The script automatically recognizes and handles these version formats:
14.3-RELEASE- Stable releases15.0-BETA3- Beta versions13.4-RC1- Release candidates- Any format matching:
X.Y-RELEASE|BETAX|RCX
To change the default version when no arguments are provided, modify the
DEFAULT_VERSION constant in main.ts.
📁 Project Structure#
freebsd-up/
├── main.ts # CLI entry point with Cliffy command routing
├── deno.json # Deno configuration with dependencies
├── deno.lock # Dependency lock file
├── README.md # This file
└── src/ # Core functionality modules
├── config.ts # Configuration file parsing and management
├── constants.ts # Configuration constants
├── context.ts # Application context and database setup
├── db.ts # Database schema and migrations
├── images.ts # Image management functions
├── migrations.ts # Database migration utilities
├── network.ts # Network bridge management
├── oras.ts # OCI registry operations via ORAS
├── state.ts # VM state management functions
├── types.ts # TypeScript type definitions
├── utils.ts # Core VM utilities and QEMU interface
├── volumes.ts # Volume management functions
├── api/ # HTTP API server
│ ├── images.ts # Image management API endpoints
│ ├── machines.ts # VM management API endpoints
│ ├── volumes.ts # Volume management API endpoints
│ ├── utils.ts # API utilities and helpers
│ └── mod.ts # API server entry point
└── subcommands/ # CLI subcommand implementations
├── images.ts # List images command
├── inspect.ts # VM inspection command
├── login.ts # OCI registry login command
├── logout.ts # OCI registry logout command
├── logs.ts # VM logging command
├── ps.ts # VM listing command
├── pull.ts # Pull image from registry command
├── push.ts # Push image to registry command
├── restart.ts # VM restart command
├── rm.ts # VM removal command
├── rmi.ts # Remove image command
├── run.ts # Run VM command
├── serve.ts # HTTP API server command
├── start.ts # VM start command
├── stop.ts # VM stop command
├── tag.ts # Tag image command
└── volume.ts # Volume management commands
Dependencies#
The project uses the following key dependencies:
- @paralleldrive/cuid2 - Unique ID generation for VMs
- @cliffy/command - Modern command-line argument parsing and subcommands
- @cliffy/flags - Command-line flag parsing
- @cliffy/prompt - Interactive prompts for CLI
- @cliffy/table - Formatted table output for VM listings
- @db/sqlite - SQLite database for VM state persistence
- @soapbox/kysely-deno-sqlite - SQLite dialect for Kysely
- @es-toolkit/es-toolkit - Modern utility functions (replacing lodash)
- @std/io - Standard I/O utilities
- @std/path - Path manipulation utilities
- @std/toml - TOML configuration file parsing
- @zod/zod - TypeScript-first schema validation
- kysely - Type-safe SQL query builder
- chalk - Terminal styling and colors
- dayjs - Date formatting and manipulation
- effect - Functional effect system for error handling and async operations
- moniker - Unique name generation for VMs
- hono - Fast and lightweight web framework for the HTTP API server
🤝 Contributing#
Contributions are welcome! Feel free to:
- Report bugs
- Suggest features
- Submit pull requests
- Improve documentation
📝 License#
This project is licensed under the Mozilla Public License 2.0. See the LICENSE file for details.
🔗 Useful Links#
NOTE
This tool is designed for development and testing purposes. For production FreeBSD deployments, consider using proper installation methods.