Lima enables you to run a Linux machine on your Mac for free. This tutorial helps you install Lima, launch a Linux VM, verify shared files, and run a web server in a container accessible via your browser.
If you want the concepts first, read What Is Lima? and come back. This article stays hands-on.
What You’ll Build
A working Lima setup: an Ubuntu virtual machine (VM) running on your Mac, managed from your terminal, serving a containerized nginx web page at localhost:8080.
What success looks like: you type curl localhost:8080 on your Mac and get a “Welcome to nginx!” page served from Linux.
What You’ll Learn
- How to install Lima and start your first Linux VM.
- How to run Linux commands from your Mac terminal.
- How file sharing between your Mac and the VM works.
- How to run a container with
nerdctland reach it from your Mac.
Time estimate: about 30 minutes, mostly waiting for downloads. Difficulty: beginner.
Prerequisites
You need:
- A Mac with Homebrew installed. Apple Silicon or Intel both work.
- macOS 13 or newer. Lima’s fast
vzdriver needs it. Older macOS versions fall back to the slower QEMU driver. - About 5 GB of free disk space for the VM image and container images.
- A terminal you’re comfortable with.
This tutorial covers Lima 2.x on Apple Silicon, verified against Lima 2.2. The commands have been stable since Lima 1.0, but the defaults behind them have not: Lima 2.0 stopped mounting /tmp/lima by default and renamed template locators, so steps written for Lima 1.x can fail on 2.x. Step 1 asks for that mount explicitly, which works on both.
You don’t need:
- Docker, Docker Desktop, or any container experience.
- Any virtualization knowledge. Lima handles the VM plumbing.
Everything in this tutorial is reversible; one command at the end removes the VM and all contents.
Setup
Install Lima
Install Lima with Homebrew:
brew install limaConfirm it installed:
limactl --versionYou should see: a version string such as limactl version 2.2.2. Your version number will differ, and that’s fine.
Checkpoint: If limactl prints a version, you’re ready. If your shell says command not found, jump to Troubleshooting.
Tutorial Steps
Step 1: Start your first Linux VM
Lima calls each VM an instance. Start the default one:
limactl start --containerd user --mount '/tmp/lima:w'Both flags matter:
--containerd userasks for user-mode containerd, the container engine behind Step 4, along with thenerdctlcommand. Lima 2.x enables it by default for Linux guests, so the flag is insurance: it keeps this tutorial working on older Lima versions and if the default changes again. Runlimactl infoand look atdefaultTemplate.containerdto see what your version does.--mount '/tmp/lima:w'shares/tmp/limabetween your Mac and the VM, and the:wsuffix makes it writable. Lima 2.0 stopped mounting that directory by default, and Step 3 uses it. Lima creates the directory on your Mac if it isn’t there yet.
On the first run, it asks how to create the instance. Pick Proceed with the current configuration and press Enter. The defaults give you an Ubuntu VM with 4 CPUs, 4 GiB of memory, and a 100 GiB disk that uses space only as needed.
The first start downloads an Ubuntu image, so give it a few minutes.
You should see: log lines about downloading and booting, ending with:
READY. Run `lima` to open the shell.What just happened: Lima downloaded Ubuntu, created a VM named default, booted it, and wired up file sharing and port forwarding. You now have a Linux kernel running on your Mac.
Checkpoint: Run limactl list. The default instance shows Running in the STATUS column:
NAME STATUS SSH VMTYPE ARCH CPUS MEMORY DISK DIR
default Running 127.0.0.1:60022 vz aarch64 4 4GiB 100GiB ~/.lima/defaultYour SSH port and architecture may differ. Running is what matters.
Step 2: Run Linux commands from your Mac
The lima command runs whatever you give it inside the VM. Prove you’re talking to Linux:
lima uname -aYou should see: a line starting with Linux lima-default, ending in aarch64 GNU/Linux on Apple Silicon or x86_64 GNU/Linux on Intel.
Your Mac would have said Darwin. This output comes from the Ubuntu kernel inside the VM.
Run lima with no arguments to open an interactive shell in the VM, then exit to come back to macOS. For the rest of this tutorial, stay on the Mac side and prefix commands with lima.
Checkpoint: lima whoami prints your macOS username. Lima creates a matching user inside the guest so file permissions line up.
Step 3: See file sharing in action
Your instance has two shares. /tmp/lima is writable in both directions, thanks to the --mount '/tmp/lima:w' flag from Step 1. Your Mac home directory is mounted at the same path inside the guest, but read-only. Test both.
Create a file on your Mac:
echo "hello from macOS" > /tmp/lima/from-mac.txtRead it from inside Linux:
lima cat /tmp/lima/from-mac.txtYou should see: hello from macOS.
Now go the other way. Write a file from the Linux side:
lima sh -c 'echo "hello from Linux" > /tmp/lima/from-linux.txt'Read it on your Mac, with no lima prefix this time:
cat /tmp/lima/from-linux.txtYou should see: hello from Linux.
Now confirm the other share is read-only:
lima sh -c "echo nope > $HOME/should-fail.txt"You should see: an error ending in Read-only file system.
What just happened: both systems see the same files under /tmp/lima with no copying or syncing. Your home directory also appears inside the guest so you can read your projects, but the read-only mount keeps a misbehaving VM from writing to your Mac.
Watch which shell expands your paths. $HOME above expands on your Mac before the command reaches the VM, which is why it lands on the mounted /Users/you. Inside the guest, ~ is the VM’s own home at /home/you.linux, which is writable and invisible to your Mac, so it is the wrong place for files you want to share.
Checkpoint: If both reads worked and the home write was refused, file sharing is healthy. Clean up the test files:
rm /tmp/lima/from-mac.txt /tmp/lima/from-linux.txtStep 4: Run a container and reach it from your Mac
The --containerd user flag from Step 1 gave your instance containerd and nerdctl, a command that works like docker. Start an nginx web server:
lima nerdctl run -d --name web -p 8080:80 nginx:alpineYou should see: image download progress, then a long container ID on the last line.
Now ask for the page from your Mac:
curl localhost:8080You should see: HTML containing Welcome to nginx!. Opening http://localhost:8080 in your browser shows the same page.
What just happened: The container runs inside the VM and listens on the VM’s port 8080. Lima noticed the port binding and forwarded it to your Mac automatically, so localhost works as if the server were native.
Checkpoint: lima nerdctl ps lists the web container with a status of Up.
Verification
You’re done when all three are true:
limactl listshows thedefaultinstance asRunning.lima unameprintsLinux.curl localhost:8080returns the nginx welcome page.
Then clean up the tutorial container:
lima nerdctl rm -f webWhen you’re not using the VM, stop it to free memory:
limactl stopStart it again anytime with limactl start. Your VM and its contents survive stops. To remove Lima entirely, limactl delete default deletes the VM and brew uninstall lima removes the tool.
Troubleshooting
Problem: limactl: command not found.
Symptoms: The shell can’t find limactl right after installing.
Solution: Your shell hasn’t picked up Homebrew’s path. Run eval "$(brew shellenv)" or open a new terminal window.
If that doesn’t work: run brew list lima to confirm the install succeeded, then brew doctor to check your Homebrew setup.
Problem: the first start hangs or takes forever
Symptoms: limactl start sits on a download for many minutes.
Solution: The first start pulls an Ubuntu image of several hundred megabytes. On slow connections, this takes a while, and later starts skip the download. Let it finish.
If that doesn’t work: press Ctrl+C, then run limactl start again. Downloads resume from cache, and a corrupted download restarts cleanly.
Problem: Read-only file system when writing a file
Symptoms: writing anywhere under your Mac home directory from inside the VM fails.
Solution: That’s by design, as Step 3 shows. Your home directory mounts read-only for safety. Write to /tmp/lima instead, which is shared in both directions.
If that doesn’t work: /tmp/lima is read-only too, or missing, when the instance was created before Lima 2.0 dropped that mount or without the --mount flag from Step 1. Add it to an existing instance:
limactl stop
limactl edit default --set '.mounts += [{"location": "/tmp/lima", "writable": true}]'
limactl startConfirm it took with lima mount | grep /tmp/lima, which should report rw.
Problem: nerdctl: command not found
Symptoms: Step 4 fails with /bin/bash: line 1: nerdctl: command not found.
Solution: The instance was created without containerd. Lima 2.x enables it by default, so this points at an instance created by an older Lima or from a template that turns it off. Enable it on the existing instance:
limactl stop
limactl edit default --set '.containerd.user=true'
limactl startLima installs nerdctl inside the VM on the next start. Rerun Step 4 afterward.
If that doesn’t work: run grep -A2 '^containerd:' ~/.lima/default/lima.yaml on your Mac. If user still shows false, the edit didn’t save; rerun the limactl edit command.
Problem: port 8080 is already taken
Symptoms: the container starts, but curl localhost:8080 returns something that isn’t nginx, or the run command fails to bind.
Solution: Another app on your Mac owns 8080. Remove the container with lima nerdctl rm -f web, then rerun Step 4 with -p 8081:80 and curl localhost:8081.
If that doesn’t work: lsof -i :8080 on your Mac shows which process holds the port.
Next Steps
To learn more:
- Read What Is Lima? for the mental model behind what you just built: the hypervisor, the mounts, and the port forwarder.
- Browse the Lima documentation for configuration, templates, and drivers.
To extend this project:
- Try another template:
limactl start --name=docker template:dockergives you a VM with a real Docker daemon, so thedockercommand works against it. Lima 2.0 renamed the oldertemplate://dockerform, which still works but warns. - Give the VM more or less hardware with
limactl edit default, which opens the instance’s YAML configuration. - If you want a drop-in
dockerreplacement with one command, look at Colima, which builds on Lima.
References
- Lima documentation, the official guide covering installation, templates, mounts, and port forwarding.
- Homebrew, the macOS package manager used to install Lima.
- Colima, a Lima-based tool that provides a Docker-compatible runtime.

Comments #