The original goal of Lima was to promote containerd including nerdctl (contaiNERD ctl)
to Mac users, but Lima can be used for non-container applications as well.
Lima also supports non-macOS hosts (Linux, NetBSD, etc.).
1 - Installation
NOTE
Lima is not regularly tested on ARM Mac (due to lack of CI).
Prerequisite:
QEMU 7.0 or later (Required, only if QEMU driver is used)
brew install lima
Homebrew formula is available here.
Supports macOS and Linux.
git clone https://github.com/lima-vm/lima.git
cd lima
make
make install
To change the build configuration, run make config or make menuconfig.
This requires kconfig tools installed, it is also possible to edit .config.
The default configuration can be found in the file config.mk (make syntax).
Kconfig tools
The tools are available as either “kconfig-frontends” or “kbuild-standalone”.
There is one conf for the text, and one mconf for the menu interface.
A python implementation is available at https://pypi.org/project/kconfiglib.
It can be installed with pip install --user kconfiglib, including guiconfig.
2 - Usage
Starting a Linux instance
Run limactl start <INSTANCE> to create and start the first instance.
The <INSTANCE> name defaults to “default”.
$ limactl start
? Creating an instance "default" [Use arrows to move, type to filter]
> Proceed with the current configuration
Open an editor to review or modify the current configuration
Choose another template (docker, podman, archlinux, fedora, ...)
Exit
...
INFO[0029] READY. Run `lima` to open the shell.
Choose Proceed with the current configuration, and wait until “READY” to be printed on the host terminal.
For automation, --tty=false flag can be used for disabling the interactive user interface.
Customization
To create an instance “default” from a template “docker”:
If you have installed Lima by make install, the nerdctl.lima command is also available as nerdctl.
If you have installed Lima by brew install lima, you may make an alias (or a symlink) by yourself:
alias nerdctl=nerdctl.lima
The "Tier 1" yamls (marked with ⭐) are regularly tested on the CI.
Other yamls are tested only occasionally and manually.
5 - Command Reference
5.1 - completion
limactl completion
Generate the autocompletion script for the specified shell
Synopsis
Generate the autocompletion script for limactl for the specified shell.
See each sub-command’s help for details on how to use the generated script.
Options
-h, --help help for completion
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
You will need to start a new shell for this setup to take effect.
limactl completion bash
Options
-h, --help help for bash
--no-descriptions disable completion descriptions
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
SEE ALSO
limactl completion - Generate the autocompletion script for the specified shell
5.3 - completion fish
limactl completion fish
Generate the autocompletion script for fish
Synopsis
Generate the autocompletion script for the fish shell.
To load completions in your current shell session:
limactl completion fish | source
To load completions for every new session, execute once:
limactl completion fish > ~/.config/fish/completions/limactl.fish
You will need to start a new shell for this setup to take effect.
limactl completion fish [flags]
Options
-h, --help help for fish
--no-descriptions disable completion descriptions
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
SEE ALSO
limactl completion - Generate the autocompletion script for the specified shell
5.4 - completion powershell
limactl completion powershell
Generate the autocompletion script for powershell
Synopsis
Generate the autocompletion script for powershell.
To load completions in your current shell session:
To load completions for every new session, add the output of the above command
to your powershell profile.
limactl completion powershell [flags]
Options
-h, --help help for powershell
--no-descriptions disable completion descriptions
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
SEE ALSO
limactl completion - Generate the autocompletion script for the specified shell
5.5 - completion zsh
limactl completion zsh
Generate the autocompletion script for zsh
Synopsis
Generate the autocompletion script for the zsh shell.
If shell completion is not already enabled in your environment you will need
to enable it. You can execute the following once:
echo "autoload -U compinit; compinit" >> ~/.zshrc
To load completions in your current shell session:
source <(limactl completion zsh)
To load completions for every new session, execute once:
You will need to start a new shell for this setup to take effect.
limactl completion zsh [flags]
Options
-h, --help help for zsh
--no-descriptions disable completion descriptions
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
SEE ALSO
limactl completion - Generate the autocompletion script for the specified shell
5.6 - copy
limactl copy
Copy files between host and guest
Synopsis
Copy files between host and guest
Prefix guest filenames with the instance name and a colon.
Example: limactl copy default:/etc/os-release .
limactl copy SOURCE ... TARGET [flags]
Options
-h, --help help for copy
-r, --recursive copy directories recursively
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
To create an instance "default" from the default Ubuntu template:
$ limactl create
To create an instance "default" from a template "docker":
$ limactl create --name=default template://docker
To create an instance "default" with modified parameters:
$ limactl create --cpus=2 --memory=2
To create an instance "default" with yq expressions:
$ limactl create --set='.cpus = 2 | .memory = "2GiB"'
To see the template list:
$ limactl create --list-templates
To create an instance "default" from a local file:
$ limactl create --name=default /usr/local/share/lima/templates/fedora.yaml
To create an instance "default" from a remote URL (use carefully, with a trustable source):
$ limactl create --name=default https://raw.githubusercontent.com/lima-vm/lima/master/examples/alpine.yaml
To create an instance "local" from a template passed to stdin (--name parameter is required):
$ cat template.yaml | limactl create --name=local -
Options
--arch string machine architecture (x86_64, aarch64, riscv64)
--containerd string containerd mode (user, system, user+system, none)
--cpus int number of CPUs
--disk float32 disk size in GiB
--dns ipSlice specify custom DNS (disable host resolver) (default [])
-h, --help help for create
--list-templates list available templates and exit
--memory float32 memory in GiB
--mount strings directories to mount, suffix ':w' for writable (Do not specify directories that overlap with the existing mounts)
--mount-type string mount type (reverse-sshfs, 9p, virtiofs)
--mount-writable make all mounts writable
--name string override the instance name
--network strings additional networks, e.g., "vzNAT" or "lima:shared" to assign vmnet IP
--plain plain mode. Disable mounts, port forwarding, containerd, etc.
--rosetta enable Rosetta (for vz instances)
--set string modify the template inplace, using yq syntax
--video enable video output (has negative performance impact for QEMU)
--vm-type string virtual machine type (qemu, vz)
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
-f, --force forcibly kill the processes
-h, --help help for delete
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
Create a disk:
$ limactl disk create DISK --size SIZE [--format qcow2]
List existing disks:
$ limactl disk ls
Delete a disk:
$ limactl disk delete DISK
Options
-h, --help help for disk
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
To create a new disk:
$ limactl disk create DISK --size SIZE [--format qcow2]
Options
--format string specify the disk format (default "qcow2")
-h, --help help for create
--size string configure the disk size
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
To delete a disk:
$ limactl disk delete DISK
To delete multiple disks:
$ limactl disk delete DISK1 DISK2 ...
Options
-f, --force force delete
-h, --help help for delete
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
Emergency recovery! If an instance is force stopped, it may leave a disk locked while not actually using it.
To unlock a disk:
$ limactl disk unlock DISK
To unlock multiple disks:
$ limactl disk unlock DISK1 DISK2 ...
Options
-h, --help help for unlock
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--cpus int number of CPUs
--dns ipSlice specify custom DNS (disable host resolver) (default [])
-h, --help help for edit
--memory float32 memory in GiB
--mount strings directories to mount, suffix ':w' for writable (Do not specify directories that overlap with the existing mounts)
--mount-type string mount type (reverse-sshfs, 9p, virtiofs)
--mount-writable make all mounts writable
--network strings additional networks, e.g., "vzNAT" or "lima:shared" to assign vmnet IP
--rosetta enable Rosetta (for vz instances)
--set string modify the template inplace, using yq syntax
--video enable video output (has negative performance impact for QEMU)
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
Start the default instance:
$ limactl start
Open a shell:
$ lima
Run a container:
$ lima nerdctl run -d --name nginx -p 8080:80 nginx:alpine
Stop the default instance:
$ limactl stop
See also template YAMLs: /usr/local/share/lima/templates
Options
--debug debug mode
-h, --help help for limactl
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
SEE ALSO
limactl completion - Generate the autocompletion script for the specified shell
The output can be presented in one of several formats, using the –format flag.
–format json - output in json format
–format yaml - output in yaml format
–format table - output in table format
–format ‘{{ }}’ - if the format begins and ends with ‘{{ }}’, then it is used as a go template.
These functions are available to go templates:
indent : add spaces to beginning of each line
missing : return message if the text is empty
The following legacy flags continue to function:
–json - equal to ‘–format json’
limactl list [flags] [INSTANCE]...
Options
--all-fields Show all fields
-f, --format string output format, one of: json, yaml, table, go-template (default "table")
-h, --help help for list
--json JSONify output
--list-fields List fields available for format
-q, --quiet Only show names
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
Protect an instance to prohibit accidental removal
Synopsis
Protect an instance to prohibit accidental removal via the ’limactl delete’ command.
The instance is not being protected against removal via ‘/bin/rm’, Finder, etc.
limactl protect INSTANCE [INSTANCE, ...] [flags]
Options
-h, --help help for protect
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
lima command is provided as an alias for limactl shell $LIMA_INSTANCE. $LIMA_INSTANCE defaults to “default”.
By default, the first ‘ssh’ executable found in the host’s PATH is used to connect to the Lima instance.
A custom ssh alias can be used instead by setting the $SSH environment variable.
Hint: try –debug to show the detailed logs, if it seems hanging (mostly due to some SSH issue).
limactl shell [flags] INSTANCE [COMMAND...]
Options
-h, --help help for shell
--shell string shell interpreter, e.g. /bin/bash
--workdir string working directory
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
Show the ssh command line (DEPRECATED; use ssh -F instead)
Synopsis
Show the ssh command line (DEPRECATED)
WARNING: ’limactl show-ssh’ is deprecated.
Instead, use ‘ssh -F ~/.lima/default/ssh.config lima-default’ .
limactl show-ssh [flags] INSTANCE
Examples
"cmd" format (default): Full ssh command line.
$ limactl show-ssh --format=cmd default
ssh -o IdentityFile="/Users/example/.lima/_config/user" -o User=example -o Hostname=127.0.0.1 -o Port=60022 lima-default
"args" format: Similar to the cmd format but omits "ssh" and the destination address
$ limactl show-ssh --format=args default
-o IdentityFile="/Users/example/.lima/_config/user" -o User=example -o Hostname=127.0.0.1 -o Port=60022
"options" format: ssh option key value pairs
$ limactl show-ssh --format=options default
IdentityFile="/Users/example/.lima/_config/user"
User=example
Hostname=127.0.0.1
Port=60022
"config" format: ~/.ssh/config format
$ limactl show-ssh --format=config default
Host lima-default
IdentityFile "/Users/example/.lima/_config/user "
User example
Hostname 127.0.0.1
Port 60022
To show the config file path:
$ limactl ls --format='{{.SSHConfigFile}}' default
/Users/example/.lima/default/ssh.config
Options
-f, --format string Format: cmd, args, options, config (default "cmd")
-h, --help help for show-ssh
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
-h, --help help for apply
--tag string name of the snapshot
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
-h, --help help for create
--tag string name of the snapshot
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
-h, --help help for delete
--tag string name of the snapshot
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
-h, --help help for list
-q, --quiet Only show tags
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
To create an instance "default" (if not created yet) from the default Ubuntu template, and start it:
$ limactl start
To create an instance "default" from a template "docker", and start it:
$ limactl start --name=default template://docker
'limactl start' also accepts the 'limactl create' flags such as '--set'.
See the examples in 'limactl create --help'.
Options
--arch string [limactl create] machine architecture (x86_64, aarch64, riscv64)
--containerd string [limactl create] containerd mode (user, system, user+system, none)
--cpus int [limactl create] number of CPUs
--disk float32 [limactl create] disk size in GiB
--dns ipSlice [limactl create] specify custom DNS (disable host resolver) (default [])
-h, --help help for start
--list-templates [limactl create] list available templates and exit
--memory float32 [limactl create] memory in GiB
--mount strings [limactl create] directories to mount, suffix ':w' for writable (Do not specify directories that overlap with the existing mounts)
--mount-type string [limactl create] mount type (reverse-sshfs, 9p, virtiofs)
--mount-writable [limactl create] make all mounts writable
--name string [limactl create] override the instance name
--network strings [limactl create] additional networks, e.g., "vzNAT" or "lima:shared" to assign vmnet IP
--plain [limactl create] plain mode. Disable mounts, port forwarding, containerd, etc.
--rosetta [limactl create] enable Rosetta (for vz instances)
--set string [limactl create] modify the template inplace, using yq syntax
--timeout duration duration to wait for the instance to be running before timing out (default 10m0s)
--video [limactl create] enable video output (has negative performance impact for QEMU)
--vm-type string [limactl create] virtual machine type (qemu, vz)
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
-f, --force force stop the instance
-h, --help help for stop
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
Generate the content of the /etc/sudoers.d/lima file
Synopsis
Generate the content of the /etc/sudoers.d/lima file for enabling vmnet.framework support.
The content is written to stdout, NOT to the file.
This command must not run as the root.
See /usr/local/share/doc/lima/docs/network.md for the usage.
To generate the /etc/sudoers.d/lima file:
$ limactl sudoers | sudo tee /etc/sudoers.d/lima
To validate the existing /etc/sudoers.d/lima file:
$ limactl sudoers --check /etc/sudoers.d/lima
Options
--check check that the sudoers file is up-to-date with "~/.lima/_config/networks.yaml"
-h, --help help for sudoers
Options inherited from parent commands
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
--debug debug mode
--log-level string Set the logging level [trace, debug, info, warn, error]
--tty Enable TUI interactions such as opening an editor. Defaults to true when stdout is a terminal. Set to false for automation.
The vmType can be specified only on creating the instance.
The vmType of existing instances cannot be changed.
See the following flowchart to choose the best vmType for you:
flowchart
host{"Host OS"} -- "Windows" --> wsl2["WSL2"]
host -- "Linux" --> qemu["QEMU"]
host -- "macOS" --> intel_on_arm{"Need to run <br> Intel binaries <br> on ARM?"}
intel_on_arm -- "Yes" --> just_elf{"Just need to <br> run Intel userspace (fast), <br> or entire Intel VM (slow)?"}
just_elf -- "Userspace (fast)" --> vz
just_elf -- "VM (slow)" --> qemu
intel_on_arm -- "No" --> vz["VZ"]
QEMU
“qemu” option makes use of QEMU to run guest operating system.
This option is used by default if “vmType” is not set.
VZ
Warning
“vz” mode is experimental
⚡ Requirement
Lima >= 0.14, macOS >= 13.0
“vz” option makes use of native virtualization support provided by macOS Virtualization.Framework.
An example configuration:
limactl start --vm-type=vz --mount-type=virtiofs
# Example to run ubuntu using vmType: vz instead of qemu (Default)vmType:"vz"images:- location:"https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-amd64.img"arch:"x86_64"- location:"https://cloud-images.ubuntu.com/releases/22.04/release/ubuntu-22.04-server-cloudimg-arm64.img"arch:"aarch64"mounts:- location:"~"mountType:"virtiofs"
Caveats
“vz” option is only supported on macOS 13 or above
Virtualization.framework doesn’t support running “intel guest on arm” and vice versa
Known Issues
“vz” doesn’t support legacyBIOS: true option, so guest machine like centos-stream, archlinux, oraclelinux will not work
When running lima using “vz”, ${LIMA_HOME}/<INSTANCE>/serial.log will not contain kernel boot logs
On Intel Mac with macOS prior to 13.5, Linux kernel v6.2 (used by Ubuntu 23.04, Fedora 38, etc.) is known to be unbootable on vz.
kernel v6.3 and later should boot, as long as it is booted via GRUB.
https://github.com/lima-vm/lima/issues/1577#issuecomment-1565625668
The issue is fixed in macOS 13.5.
WSL2
Warning
“wsl2” mode is experimental
⚡ Requirement
Lima >= 0.18 + (Windows >= 10 Build 19041 OR Windows 11)
“wsl2” option makes use of native virtualization support provided by Windows’ wsl.exe (more info).
# Example to run Fedora using vmType: wsl2vmType:wsl2images:# Source: https://github.com/runfinch/finch-core/blob/main/Dockerfile- location:"https://deps.runfinch.com/common/x86-64/finch-rootfs-production-amd64-1690920103.tar.zst"arch:"x86_64"digest:"sha256:53f2e329b8da0f6a25e025d1f6cc262ae228402ba615ad095739b2f0ec6babc9"mountType:wsl2 containerd:system:trueuser:false
Caveats
“wsl2” option is only supported on newer versions of Windows (roughly anything since 2019)
Known Issues
“wsl2” currently doesn’t support many of Lima’s options. See this file for the latest supported options.
When running lima using “wsl2”, ${LIMA_HOME}/<INSTANCE>/serial.log will not contain kernel boot logs
WSL2 requires a tar formatted rootfs archive instead of a VM image
Windows doesn’t ship with ssh.exe, gzip.exe, etc. which are used by Lima at various points. The easiest way around this is to run winget install -e --id Git.MinGit (winget is now built in to Windows as well), and add the resulting C:\Program Files\Git\usr\bin\ directory to your path.
6.2 - Intel-on-ARM and ARM-on-Intel
Lima supports two modes for running Intel-on-ARM and ARM-on-Intel:
Lima can run a VM with a foreign architecture, just by specifying arch in the YAML.
arch:"x86_64"# arch: "aarch64"images:- location:"https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"arch:"x86_64"- location:"https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-arm64.img"arch:"aarch64"# Disable mounts and containerd, otherwise booting up may timeout if the host is slowmounts:[]containerd:system:falseuser:false
Running a VM with a foreign architecture is extremely slow.
Consider using Fast mode or Fast mode 2 whenever possible.
This mode uses QEMU User Mode Emulation.
QEMU User Mode Emulation is significantly faster than QEMU System Mode Emulation, but it often sacrifices compatibility.
Set up:
lima sudo systemctl start containerd
lima sudo nerdctl run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28@sha256:66e11bea77a5ea9d6f0fe79b57cd2b189b5d15b93a2bdb925be22949232e4e55 --install all
Run containers:
$ lima nerdctl run --platform=amd64 --rm alpine uname -m
x86_64
$ lima nerdctl run --platform=arm64 --rm alpine uname -m
aarch64
Build and push container images:
$ lima nerdctl build --platform=amd64,arm64 -t example.com/foo:latest .
$ lima nerdctl push --all-platforms example.com/foo:latest
Warning
“vz” mode, including support for Rosetta, is experimental
⚡ Requirement
Lima >= 0.14, macOS >= 13.0, ARM
Rosetta is known to be much faster than QEMU User Mode Emulation.
Rosetta is available for VZ instances on ARM hosts.
limactl start --vm-type=vz --rosetta
vmType:"vz"rosetta:# Enable Rosetta for Linux.# Hint: try `softwareupdate --install-rosetta` if Lima gets stuck at `Installing rosetta...`enabled:true# Register rosetta to /proc/sys/fs/binfmt_miscbinfmt:true
6.3 - Network
See the following flowchart to choose the best network for you:
flowchart
connect_to_vm_via{"Connect to the VM via"} -- "localhost" --> default["Default"]
connect_to_vm_via -- "IP" --> connect_from{"Connect to the VM IP from"}
connect_from -- "Host" --> vm{"VM type"}
vm -- "vz" --> vzNAT["vzNAT"]
vm -- "qemu" --> shared["socket_vmnet (shared)"]
connect_from -- "Other VMs" --> userV2["user-v2"]
connect_from -- "Other hosts" --> bridged["socket_vmnet (bridged)"]
Default user-mode network (192.168.5.0/24)
By default Lima only enables the user-mode networking aka “slirp”.
Guest IP (192.168.5.15)
The guest IP address is set to 192.168.5.15.
This IP address is not accessible from the host by design.
Use VMNet (see below) to allow accessing the guest IP from the host and other guests.
Host IP (192.168.5.2)
The loopback addresses of the host is 192.168.5.2 and is accessible from the guest as host.lima.internal.
DNS (192.168.5.3)
The DNS.
If hostResolver.enabled in lima.yaml is true, then the hostagent is going to run a DNS server over tcp and udp - each on a separate randomly selected free port. This server does a local lookup using the native host resolver, so it will deal correctly with VPN configurations and split-DNS setups, as well as mDNS, local /etc/hosts etc. For this the hostagent has to be compiled with CGO_ENABLED=1 as default Go resolver is broken.
These tcp and udp ports are then forwarded via iptables rules to 192.168.5.3:53, overriding the DNS provided by QEMU via slirp.
Currently following request types are supported:
A
AAAA
CNAME
TXT
NS
MX
SRV
For all other queries hostagent will redirect the query to the nameservers specified in /etc/resolv.conf (or, if that fails - to 8.8.8.8 and 1.1.1.1).
DNS over tcp is rarely used. It is usually only used either when user explicitly requires it, or when request+response can’t fit into a single UDP packet (most likely in case of DNSSEC), or in the case of certain management operations such as domain transfers. Neither DNSSEC nor management operations are currently supported by a hostagent, but on the off chance that the response may contain an unusually long list of records - hostagent will also listen for the tcp traffic.
During initial cloud-init bootstrap, iptables may not yet be installed. In that case the repo server is determined using the slirp DNS. After iptables has been installed, the forwarding rule is applied, switching over to the hostagent DNS.
If hostResolver.enabled is false, then DNS servers can be configured manually in lima.yaml via the dns setting. If that list is empty, then Lima will either use the slirp DNS (on Linux), or the nameservers from the first host interface in service order that has an assigned IPv4 address (on macOS).
VMNet networks
VMNet assigns a “real” IP address that is reachable from the host.
The configuration steps are different for each network type:
socket_vmnet is required for adding another guest IP that is accessible from the host and other guests.
# Install socket_vmnetbrew install socket_vmnet
# Set up the sudoers file for launching socket_vmnet from Limalimactl sudoers >etc_sudoers.d_lima
sudo install -o root etc_sudoers.d_lima /etc/sudoers.d/lima
Note
Lima before v0.12 used vde_vmnet for managing the networks.
vde_vmnet is still supported but it is deprecated and no longer documented here.
The networks are defined in $LIMA_HOME/_config/networks.yaml. If this file doesn’t already exist, it will be created with these default
settings:
Default
# Path to socket_vmnet executable. Because socket_vmnet is invoked via sudo it should be# installed where only root can modify/replace it. This means also none of the# parent directories should be writable by the user.## The varRun directory also must not be writable by the user because it will# include the socket_vmnet pid file. Those will be terminated via sudo, so replacing# the pid file would allow killing of arbitrary privileged processes. varRun# however MUST be writable by the daemon user.## None of the paths segments may be symlinks, why it has to be /private/var# instead of /var etc.paths:# socketVMNet requires Lima >= 0.12 .# socketVMNet has precedence over vdeVMNet.socketVMNet:/opt/socket_vmnet/bin/socket_vmnet# vdeSwitch and vdeVMNet are DEPRECATED.vdeSwitch:/opt/vde/bin/vde_switchvdeVMNet:/opt/vde/bin/vde_vmnetvarRun:/private/var/run/limasudoers:/private/etc/sudoers.d/limagroup:everyonenetworks:shared:mode:sharedgateway:192.168.105.1dhcpEnd:192.168.105.254netmask:255.255.255.0bridged:mode:bridgedinterface:en0# bridged mode doesn't have a gateway; dhcp is managed by outside networkhost:mode:hostgateway:192.168.106.1dhcpEnd:192.168.106.254netmask:255.255.255.0
Instances can then reference these networks:
limactl start --network=lima:shared
networks:# Lima can manage the socket_vmnet daemon for networks defined in $LIMA_HOME/_config/networks.yaml automatically.# The socket_vmnet binary must be installed into a secure location only alterable by the admin.# The same applies to vde_switch and vde_vmnet for the deprecated VDE mode.# - lima: shared# # MAC address of the instance; lima will pick one based on the instance name,# # so DHCP assigned ip addresses should remain constant over instance restarts.# macAddress: ""# # Interface name, defaults to "lima0", "lima1", etc.# interface: ""
The network daemon is started automatically when the first instance referencing them is started,
and will stop automatically once the last instance has stopped. Daemon logs will be stored in the
$LIMA_HOME/_networks directory.
The IP address is automatically assigned by macOS’s bootpd.
If the IP address is not assigned, try the following commands:
networks:# Lima can also connect to "unmanaged" networks addressed by "socket". This# means that the daemons will not be controlled by Lima, but must be started# before the instance. The interface type (host, shared, or bridged) is# configured in socket_vmnet and not in lima.# - socket: "/var/run/socket_vmnet"
vzNAT
Warning
“vz” mode is experimental
⚡ Requirement
Lima >= 0.14, macOS >= 13.0
For VZ instances, the “vzNAT” network can be configured as follows:
limactl start --vm-type=vz --network=vzNAT
networks:- vzNAT:true
The range of the IP address is not specifiable.
The “vzNAT” network does not need the socket_vmnet binary and the sudoers file.
Lima user-v2 network
⚡ Requirement
Lima >= 0.16.0
user-v2 network provides a user-mode networking similar to the default user-mode network and also provides support for vm -> vm communication.
Warning
This network mode is experimental
To enable this network mode, define a network with mode: user-v2 in networks.yaml
By default, the below network configuration is already applied (Since v0.18).
Lima supports several methods for mounting the host filesystem into the guest.
The default mount type is shown in the following table:
Lima Version
Default
< 0.10
reverse-sshfs + Builtin SFTP server
>= 0.10
reverse-sshfs + OpenSSH SFTP server
>= 0.17
reverse-sshfs + OpenSSH SFTP server for QEMU, virtiofs for VZ
>= 1.0 (Planned)
9p for QEMU, virtiofs for VZ
Mount types
reverse-sshfs
The “reverse-sshfs” mount type exposes the host filesystem by running an SFTP server on the host.
While the host works as an SFTP server, the host does not open any TCP port,
as the host initiates an SSH connection into the guest and let the guest connect to the SFTP server via the stdin.
An example configuration:
limactl start --mount-type=reverse-sshfs
mountType:"reverse-sshfs"mounts:- location:"~"sshfs:# Enabling the SSHFS cache will increase performance of the mounted filesystem, at# the cost of potentially not reflecting changes made on the host in a timely manner.# Warning: It looks like PHP filesystem access does not work correctly when# the cache is disabled.# 🟢 Builtin default: truecache:null# SSHFS has an optional flag called 'follow_symlinks'. This allows mounts# to be properly resolved in the guest os and allow for access to the# contents of the symlink. As a result, symlinked files & folders on the Host# system will look and feel like regular files directories in the Guest OS.# 🟢 Builtin default: falsefollowSymlinks:null# SFTP driver, "builtin" or "openssh-sftp-server". "openssh-sftp-server" is recommended.# 🟢 Builtin default: "openssh-sftp-server" if OpenSSH SFTP Server binary is found, otherwise "builtin"sftpDriver:null
The default value of sftpDriver has been set to “openssh-sftp-server” since Lima v0.10, when an OpenSSH SFTP Server binary
such as /usr/libexec/sftp-server is detected on the host.
Lima prior to v0.10 had used “builtin” as the SFTP driver.
Caveats
A mount is disabled when the SSH connection was shut down.
A compromised sshfs process in the guest may have an access to unexposed host directories.
9p
Warning
“9p” mode is experimental
The “9p” mount type is implemented by using QEMU’s virtio-9p-pci devices.
virtio-9p-pci is also known as “virtfs”, but note that this is unrelated to virtio-fs.
An example configuration:
limactl start --vm-type=qemu --mount-type=9p
vmType:"qemu"mountType:"9p"mounts:- location:"~"9p:# Supported security models are "passthrough", "mapped-xattr", "mapped-file" and "none".# "mapped-xattr" and "mapped-file" are useful for persistent chown but incompatible with symlinks.# 🟢 Builtin default: "none" (since Lima v0.13)securityModel:null# Select 9P protocol version. Valid options are: "9p2000" (legacy), "9p2000.u", "9p2000.L".# 🟢 Builtin default: "9p2000.L"protocolVersion:null# The number of bytes to use for 9p packet payload, where 4KiB is the absolute minimum.# 🟢 Builtin default: "128KiB"msize:null# Specifies a caching policy. Valid options are: "none", "loose", "fscache" and "mmap".# Try choosing "mmap" or "none" if you see a stability issue with the default "fscache".# See https://www.kernel.org/doc/Documentation/filesystems/9p.txt# 🟢 Builtin default: "fscache" for non-writable mounts, "mmap" for writable mountscache:null
The “9p” mount type requires Lima v0.10.0 or later.
Caveats
The “9p” mount type is known to be incompatible with CentOS, Rocky Linux, and AlmaLinux as their kernel do not support CONFIG_NET_9P_VIRTIO.
virtiofs
Warning
“virtiofs” mode is experimental
⚡ Requirement
Lima >= 0.14, macOS >= 13.0
Lima >= 0.17.0, Linux, QEMU 4.2.0+, virtiofsd (Rust version)
The “virtiofs” mount type is implemented via the virtio-fs device by using apple Virtualization.Framework shared directory on macOS and virtiofsd on Linux.
Linux guest kernel must enable the CONFIG_VIRTIO_FS support for this support.
An example configuration:
limactl start --vm-type=vz --mount-type=virtiofs
vmType:"vz"# only for macOS; Linux uses 'qemu'mountType:"virtiofs"mounts:- location:"~"
Caveats
For macOS, the “virtiofs” mount type is supported only on macOS 13 or above with vmType: vz config. See also vmtype.md.
For Linux, the “virtiofs” mount type requires the Rust version of virtiofsd.
Using the version from QEMU (usually packaged as qemu-virtiofsd) will not work, as it requires root access to run.
wsl2
Warning
“wsl2” mode is experimental
⚡ Requirement
Lima >= 0.18 + (Windows >= 10 Build 19041 OR Windows 11)
The “wsl2” mount type relies on using WSL2’s native disk sharing, where the root disk is available by default at /mnt/$DISK_LETTER (e.g. /mnt/c/).
An example configuration:
limactl start --vm-type=wsl2 --mount-type=wsl2
vmType:"wsl2"mountType:"wsl2"
Caveats
WSL2 file permissions may not work exactly as expected when accessing files that are natively on the Windows disk (more info)
WSL2’s disk sharing system uses a 9P protocol server, making the performance similar to Lima’s 9p mode (more info)
The default Ubuntu image also contains LXD. Run lima sudo lxc init to set up LXD.
See also third party containerd projects based on Lima:
Rancher Desktop: Kubernetes and container management to the desktop
Colima: Docker (and Kubernetes) on macOS with minimal setup
Or third party "containers" projects compatible with Lima:
Podman Desktop: Containers and Kubernetes for application developers
“Can I run Lima with a remote Linux machine?”
Lima itself does not support connecting to a remote Linux machine, but sshocker,
the predecessor or Lima, provides similar features for remote Linux machines.
e.g., run sshocker -v /Users/foo:/home/foo/mnt -p 8080:80 <USER>@<HOST> to expose /Users/foo to the remote machine as /home/foo/mnt,
and forward localhost:8080 to the port 80 of the remote machine.
“Advantages compared to Docker for Mac?”
Lima is free software (Apache License 2.0), while Docker for Mac is not.
Configuration
“Is it possible to disable mounts, port forwarding, containerd, etc. ?”
Yes, since Lima v0.18:
limactl start --plain
plain:true
When the “plain” mode is enabled:
the YAML properties for mounts, port forwarding, containerd, etc. will be ignored
guest agent will not be running
dependency packages like sshfs will not be installed into the VM
User-specified provisioning scripts will be still executed.
QEMU
“QEMU crashes with HV_ERROR”
If you have installed QEMU v6.0.0 or later on macOS 11 via homebrew, your QEMU binary should have been already automatically signed to enable HVF acceleration.
However, if you see HV_ERROR, you might need to sign the binary manually.
if you are on macOS 10.15.7 or 11.0 or later make sure the entitlement com.apple.vm.hypervisor is not added. It only works on older macOS versions. You can clear the codesigning with codesign --remove-signature /usr/local/bin/qemu-system-x86_64 and start over.
“QEMU crashes with vmx_write_mem: mmu_gva_to_gpa XXXXXXXXXXXXXXXX failed”
This error is known to happen when running an image of RHEL8-compatible distribution such as Rocky Linux 8.x on Intel Mac.
A workaround is to set environment variable QEMU_SYSTEM_X86_64="qemu-system-x86_64 -cpu Haswell-v4".
Try softwareupdate --install-rosetta from a terminal.
Networking
“Cannot access the guest IP 192.168.5.15 from the host”
The default guest IP 192.168.5.15 is not accessible from the host and other guests.
To add another IP address that is accessible from the host and other virtual machines, enable socket_vmnet (since Lima v0.12)
or vde_vmnet (Deprecated).
It has been very hard to use Mac for developing containerized apps. A typical way is to use Docker for Mac, but it is not FLOSS. Another option is to install Docker and/or Kubernetes into VirtualBox, often via minikube, but it doesn’t propagate localhost ports, and VirtualBox also doesn’t support the ARM architecture. This session will show how to run containerd and k3s on macOS, using Lima and Rancher Desktop. Lima wraps QEMU in a simple CLI, with neat features for container users, such as filesystem sharing and automatic localhost port forwarding, as well as DNS and proxy propagation for enterprise networks. Rancher Desktop wraps Lima with k3s integration and GUI.
YAML property network: deprecated in Lima v0.7.0
and removed in Lima v0.14.0, in favor of networks
YAML property useHostResolver: deprecated in Lima v0.8.1
and removed in Lima v0.14.0,in favor of hostResolver.enabled
9.2 - Experimental features
The following features are experimental and subject to change:
mountType: 9p
mountType: virtiofs on Linux
vmType: vz and relevant configurations (mountType: virtiofs, rosetta, []networks.vzNAT)
vmType: wsl2 and relevant configurations (mountType: wsl2)
arch: riscv64
video.display: vnc and relevant configuration (video.vnc.display)
mode: user-v2 in networks.yml and relevant configuration in lima.yaml
audio.device
arch: armv7l
The following commands are experimental and subject to change:
limactl snapshot *
10 - Developers' guide
10.1 - Internal data structure
Lima home directory (${LIMA_HOME})
Defaults to ~/.lima.
Note that we intentionally avoid using ~/Library/Application Support/Lima on macOS.
We use ~/.lima so that we can have enough space for the length of the socket path,
which must be less than 104 characters on macOS.
Config directory (${LIMA_HOME}/_config)
The config directory contains global lima settings that apply to all instances.
User identity:
Lima creates a default identity and uses its public key as the authorized key
to access all lima instances. In addition lima will also configure all public
keys from ~/.ssh/*.pub as well, so the user can use the ssh endpoint without
having to specify an identity explicitly.
user: private key
user.pub: public key
Instance directory (${LIMA_HOME}/<INSTANCE>)
An instance directory contains the following files:
Metadata:
lima.yaml: the YAML
protected: empty file, used by limactl protect
cloud-init:
cidata.iso: cloud-init ISO9660 image. See cidata.iso.
disk:
basedisk: the base image
diffdisk: the diff image (QCOW2)
kernel:
kernel: the kernel
kernel.cmdline: the kernel cmdline
initrd: the initrd
QEMU:
qemu.pid: QEMU PID
qmp.sock: QMP socket
VZ:
vz.pid: VZ PID
vz-identifier: Unique machine identifier file for a VM
vz-efi: EFIVariable store file for a VM
Serial:
serial.log: default serial log (QEMU only), for debugging
serial.sock: default serial socket (QEMU only), for debugging (Usage: socat -,echo=0,icanon=0 unix-connect:serial.sock)
serialp.log: PCI serial log (QEMU (ARM) only), for debugging
serialp.sock: PCI serial socket (QEMU (ARM) only), for debugging (Usage: socat -,echo=0,icanon=0 unix-connect:serialp.sock)
serialv.log: virtio serial log, for debugging
serialv.sock: virtio serial socket (QEMU only), for debugging (Usage: socat -,echo=0,icanon=0 unix-connect:serialv.sock)
SSH:
ssh.sock: SSH control master socket
ssh.config: SSH config file for ssh -F. Not consumed by Lima itself.
VNC:
vncdisplay: VNC display host/port
vncpassword: VNC display password
Guest agent:
Each drivers use their own mode of communication
qemu: uses virtio-port io.lima-vm.guest_agent.0
vz: uses vsock port 2222
wsl2: uses free random vsock port
Host agent:
ha.pid: hostagent PID
ha.sock: hostagent REST API
ha.stdout.log: hostagent stdout (JSON lines, see pkg/hostagent/events.Event)
datadisk: the qcow2 or raw disk that is attached to an instance
lock:
in_use_by: symlink to the instance directory that is using the disk
When using vmType: vz (Virtualization.framework), on boot, any qcow2 (default) formatted disks that are specified in additionalDisks will be converted to RAW since Virtualization.framework only supports mounting RAW disks. This conversion enables additional disks to work with both Virtualization.framework and QEMU, but it has some consequences when it comes to interacting with the disks. Most importantly, a regular macOS default cp command will copy the entire virtual disk size, instead of just the used/allocated portion. The easiest way to copy only the used data is by adding the -c option to cp: cp -c old_path new_path. cp -c uses clonefile(2) to create a copy-on-write clone of the disk, and should return instantly.
ls will also only show the full/virtual size of the disks. To see the allocated space, du -h disk_path or qemu-img info disk_path can be used instead. See #1405 for more details.
Lima cache directory (~/Library/Caches/lima)
Currently hard-coded to ~/Library/Caches/lima on macOS.
<ALGO>.digest: digest of the data, in OCI format.
e.g., file name sha256.digest, with content sha256:5ba3d476707d510fe3ca3928e9cda5d0b4ce527d42b343404c92d563f82ba967
Environment variables
$LIMA_HOME: The “Lima home directory” (see above).
Default : ~/.lima
$LIMA_INSTANCE: lima ... is expanded to limactl shell ${LIMA_INSTANCE} ....
Default : default
$LIMA_SHELL: lima ... is expanded to limactl shell --shell ${LIMA_SHELL} ....
No default : will use the user’s shell configured inside the instance
$LIMA_WORKDIR: lima ... is expanded to limactl shell --workdir ${LIMA_WORKDIR} ....
No default : will attempt to use the current directory from the host