Skip to content
rguleryuzPublic

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Vessel

A lightweight, fast container runtime for macOS built from scratch in Rust.

Vessel is a Docker Desktop alternative that boots a minimal Linux VM via Apple's Virtualization.framework and runs containers through containerd + crun. No Electron, no Kubernetes, no bloat.

Why Vessel?

  • Fast: VM boots in ~7 seconds on Apple Silicon
  • Lightweight: ~160MB total (kernel + initramfs), no background Electron app
  • Native: Uses Virtualization.framework directly — near-native hypervisor performance
  • Compatible: Docker Engine API on a Unix socket, works with DOCKER_HOST
  • Multi-arch: ARM64 native + x86_64 via Rosetta 2 translation

Quick Start

# Prerequisites: Rust, Docker (for building initramfs), Xcode CLI tools
# Install musl cross-compiler
brew install filosottile/musl-cross/musl-cross

# Build everything
make build          # Build + codesign the daemon
cd vm && make all && make install  # Build VM image

# Run
make run             # Start vessel daemon

# In another terminal
vessel pull alpine:latest
vessel run -d -p 8080:80 alpine sh -c "while true; do echo -e 'HTTP/1.0 200 OK\r\n\r\nHello!' | nc -l -p 80; done"
curl http://localhost:8080    # Hello!

Features

Container Lifecycle

vessel pull nginx:alpine                          # Multi-arch OCI pull
vessel run -d alpine sleep 120                    # Run detached
vessel run -d --name myapp alpine sleep 120       # Named containers
vessel run -d -p 8080:80 alpine ...               # Port forwarding
vessel run -d -e FOO=bar alpine env               # Environment variables
vessel run -d -v ~/project:/app alpine ls /app    # Volume mounts
vessel exec <id> echo hello                       # Execute in container
vessel exec -it <id> sh                           # Interactive shell
vessel logs <id>                                  # View logs
vessel logs -f <id>                               # Follow logs
vessel ps                                         # List containers
vessel stop <id>                                  # Graceful stop (SIGTERM then SIGKILL)
vessel rm <id>                                    # Remove container
vessel images                                     # List pulled images

Build

vessel build -t myimage:latest .                  # Build via BuildKit

System

vessel version                                    # API version
vessel info                                       # CPUs, memory, OS
vessel start                                      # Check daemon status

Architecture

macOS Host
  vessel (CLI)
    |
    | Unix socket (~/.vessel/vessel.sock)
    v
  vesseld (daemon)
    |-- Docker Engine API server (axum, HTTP/1.1)
    |-- OCI image registry client
    |-- Port forward manager
    |-- VM lifecycle manager
    |
    | Virtualization.framework
    v
  Linux VM (custom kernel 6.6.10, arm64)
    |
    | tmpfs root (chroot from initramfs)
    |
    |-- containerd ──> crun (OCI runtime)
    |-- BuildKit daemon
    |-- vessel-agent
    |     |-- vsock:1024 (RPC channel)
    |     |-- vsock:1025 (port forwarding data)
    |     |-- vsock:1026 (interactive exec)
    |
    |-- virtiofs (/host -> macOS home directory)
    |-- Rosetta 2 (x86_64 binary translation)

Communication

Channel Protocol Purpose
CLI <-> Daemon HTTP over Unix socket Docker Engine API
Daemon <-> Agent vsock:1024 JSON-framed RPC (container ops)
Daemon <-> Agent vsock:1025 Raw TCP forwarding (port mapping)
Daemon <-> Agent vsock:1026 Interactive exec streaming
Host <-> VM virtiofs File sharing (volumes, image layers)

Crate Structure

vessel/
  crates/
    vessel-cli/        CLI binary (clap)
    vessel-daemon/     Daemon binary (axum, Virtualization.framework FFI)
    vessel-agent/      VM-side agent (containerd gRPC, vsock)
    vessel-api/        Shared Docker API types (serde)
    vessel-vsock/      vsock framing protocol
  proto/               containerd gRPC proto definitions
  vm/
    kernel/            Kernel download scripts
    initramfs/         Init scripts + build system

How It Works

  1. vessel pull: Daemon fetches OCI manifest from Docker Hub (resolves arm64/amd64), downloads layers to ~/Library/Application Support/Vessel/images/, transfers to VM via virtiofs, imports into containerd via ctr

  2. vessel run: Daemon sends create+start to agent over vsock, agent runs ctr run --net-host --privileged with the image, sets up port forwarding listeners if -p specified, mounts virtiofs paths for -v volumes

  3. Port forwarding (-p 8080:80): Daemon listens on host port 8080, opens vsock connection to agent port 1025, agent connects to container's port 80 on localhost (shared network namespace), bidirectional relay

  4. Volume mounts (-v ~/project:/app): Host path translated to VM virtiofs path (/Users/x/project -> /host/project), mounted inside container via mount -t virtiofs + mount --bind

  5. Interactive exec (-it): CLI connects to daemon's TCP exec proxy (port 9800), daemon opens vsock to agent port 1026, agent runs ctr task exec --tty, terminal set to raw mode for bidirectional streaming

Building

Prerequisites

  • macOS 13+ (Ventura or later)
  • Apple Silicon or Intel Mac
  • Rust toolchain (rustup)
  • Docker or OrbStack (for building the initramfs)
  • Xcode Command Line Tools (xcode-select --install)

Build Steps

# 1. Install musl cross-compiler for Linux agent binary
brew install filosottile/musl-cross/musl-cross
rustup target add aarch64-unknown-linux-musl

# 2. Build Rust binaries
make build

# 3. Build VM image (kernel + initramfs)
cd vm
make all       # Downloads kernel, cross-compiles agent, builds initramfs
make install   # Copies to ~/Library/Application Support/Vessel/

# 4. Run
make run       # Builds, codesigns, and starts the daemon

Makefile Targets

Target Description
make build Build + codesign daemon (debug)
make build-release Build + codesign (release)
make run Build, sign, and run daemon
make test Run all workspace tests
make vm-build Build kernel + initramfs
make vm-install Install VM image
make vm-rebuild Rebuild initramfs with latest agent
make clean Clean build artifacts

Configuration

Daemon socket: ~/.vessel/vessel.sock

Override with environment variable:

export DOCKER_HOST=unix://$HOME/.vessel/vessel.sock
# Now `docker` CLI works against Vessel
docker ps
docker images

VM image location: ~/Library/Application Support/Vessel/

  • vmlinux — Linux kernel (ARM64 Image)
  • initramfs.gz — Root filesystem with containerd + crun + agent

Technical Details

  • Kernel: Custom Linux 6.6.10 with virtio, vsock, overlayfs, virtiofs, FUSE built-in
  • Container runtime: crun (C-based OCI runtime, lighter than runc)
  • Image builder: BuildKit (Dockerfile support)
  • Networking: Containers share VM network namespace (--net-host), port forwarding via vsock data channels
  • Storage: tmpfs root (containers are ephemeral per VM boot), overlayfs snapshotter for container layers
  • Rosetta: x86_64 ELF binaries translated via Apple's Rosetta 2 inside the VM

Stats

  • 53 commits from design to working runtime
  • ~5000 lines of Rust code across 5 crates
  • 46 unit tests + 3 integration smoke tests
  • ~160MB VM image (40MB kernel + 120MB initramfs)
  • ~7 second VM boot time on Apple Silicon

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors