Lightweight Linux VMs on MacOS
See the codeCreate and manage lightweight Alpine VMs on MacOS with:
🔁 Seamless port forwarding
🗂️ Automatic file sharing
🎢 Bridged networking
🚀 aarch64 and x86_64 emulation
The goal of this project is to enable MacOS users to:
macpine is intended for use on modern macOS. Support for older versions of macOS and other OSes may vary.
brew install macpine # installs `alpine` command and `qemu` dependency automatically
Download the latest binary release for your system and add it to your $PATH
by moving it to e.g. /usr/local/bin/:
arch="$([ `uname -m` = 'x86_64' ] && echo 'amd64' || echo 'arm64')" # detect architecture
wget "https://github.com/beringresearch/macpine/releases/latest/download/alpine_darwin_$arch"
mv "alpine_darwin_$arch" alpine
sudo chmod +x alpine
sudo mv alpine /usr/local/bin/
#export PATH="$PATH:/usr/local/bin"
Macpine depends on QEMU >= 7.22.0:
brew install qemu
See Requirements below for a known QEMU regression and optional passwordless vmnet setup.
You can also install macpine via MacPorts:
sudo port install macpine
Building from source requires a working go compiler, and running requires qemu:
brew install go qemu
git clone https://github.com/beringresearch/macpine
cd macpine
make # compiles the project into a local bin/ directory
make install # installs binaries to /usr/local/bin
# PREFIX=/some/other/path make install installs to /some/other/path
brew install macpine or manually via brew install qemu.aarch64 instances on boot when using vmnet networking (see Troubleshooting). If you hit this, pin QEMU to 10.0.3 until it's fixed upstream.vmnet) networking require sudo for alpine start/stop/ssh/exec, unless socket_vmnet is installed and running.sudoBy default, vmnet networking (a real, LAN-reachable IP for the instance) requires root, because QEMU calls macOS's Vmnet.framework directly. Installing socket_vmnet removes that requirement: it does the one privileged step once, in the background, and macpine talks to it over a Unix socket instead.
brew install socket_vmnet
sudo brew services start socket_vmnet # one-time; runs persistently in the background
macpine detects a running socket_vmnet daemon automatically. If it isn't found, macpine transparently falls back to QEMU's native vmnet-shared networking (requiring sudo, as before).
To create and start a new instance:
alpine launch # launches with default parameters
alpine launch -a aarch64 # create an aarch64 instance
alpine launch -d 10G -c 4 -m 2048 # create an instance with a 10GB disk, 4 cpus, and 2GB of RAM
alpine launch -h # view all configuration options and defaults
Access instance via ssh:
alpine launch -s 22 # launch an instance and expose SSH port to host port 22
alpine ssh instance-name # attach shell to instance (replace `instance-name` as appropriate)
Expose additional instance ports to host:
# launch an instance, expose SSH to host port 2022 and forward host ports 8888 and 5432 to instance ports 8888 and 5432
alpine launch -s 2022 -p 8888,5432
# launch an instance, expose SSH to host port 8022, forward host port 8081 to instance port 8082, and forward
# host port 8083 to instance port 8083
alpine launch -s 8022 -p 8081:8082,8083
# launch an instance, expose SSH to host port 9022, forward host port 9091 UDP to instance port 9091 UDP,
# and forward host port 9092 UDP to instance port 9093 UDP
alpine launch -s 9023 -p 9091u,9092:9093u
Instances can be easily packaged for backup or sharing as .tar.gz files:
alpine list
NAME STATUS SSH PORTS ARCH PID TAGS
cheerful-result Running 2022 aarch64 26568
glittering-swing Running 3022 x86_64 57206 emulation,intel
alpine publish cheerful-result
This will create a file cheerful-result.tar.gz which can be imported as:
#alpine delete cheerful-result
alpine import cheerful-result.tar.gz
See all the docs for more information:
Create, control, and connect to Alpine instances.
Usage:
alpine [command]
Available Commands:
completion Generate shell autocompletions.
delete Delete instances.
edit Edit instance configurations.
exec execute a command on an instance over ssh.
help Help about any command
import Imports an instance archived with `alpine publish`.
info Display information about instances.
launch Create and start an instance.
list List instances.
pause Pause instances.
publish Publish instances.
rename Rename an instance.
restart Stop and start instances.
resume Unpause instances.
ssh Attach an interactive shell to an instance via ssh.
start Start instances.
stop Stop instances.
tag Add or remove tags from an instance.
Flags:
-h, --help help for alpine
Use "alpine [command] --help" for more information about a command.
Multiple instances in a command: some commands (delete, edit, info, pause, publish, restart, resume, start, stop)
accept multiple instance names and will repeat the operation over each unique named instance once.
Tags: using alpine tag, instances can be tagged; tags can be used in multi-instance commands (see above) e.g.
alpine start +foobar will start all instances which have had been tagged foobar with alpine tag instance-name foobar. Note that
the tag launchctl-autostart is used for auto-starting instances at login.
Shell autocompletion: shell command completion files (installed automatically with brew install macpine) can be generated with
alpine completion [bash|zsh|fish|powershell]. See alpine completion -h or the completion documentation
for more information.
1,338 followers · starred Apr 2024
9,478 followers · starred Nov 2022
5,204 followers · starred Sep 2025
4,328 followers · starred Nov 2022
Lightweight Linux VMs on MacOS
See the codeCreate and manage lightweight Alpine VMs on MacOS with:
🔁 Seamless port forwarding
🗂️ Automatic file sharing
🎢 Bridged networking
🚀 aarch64 and x86_64 emulation
The goal of this project is to enable MacOS users to:
macpine is intended for use on modern macOS. Support for older versions of macOS and other OSes may vary.
brew install macpine # installs `alpine` command and `qemu` dependency automatically
Download the latest binary release for your system and add it to your $PATH
by moving it to e.g. /usr/local/bin/:
arch="$([ `uname -m` = 'x86_64' ] && echo 'amd64' || echo 'arm64')" # detect architecture
wget "https://github.com/beringresearch/macpine/releases/latest/download/alpine_darwin_$arch"
mv "alpine_darwin_$arch" alpine
sudo chmod +x alpine
sudo mv alpine /usr/local/bin/
#export PATH="$PATH:/usr/local/bin"
Macpine depends on QEMU >= 7.22.0:
brew install qemu
See Requirements below for a known QEMU regression and optional passwordless vmnet setup.
You can also install macpine via MacPorts:
sudo port install macpine
Building from source requires a working go compiler, and running requires qemu:
brew install go qemu
git clone https://github.com/beringresearch/macpine
cd macpine
make # compiles the project into a local bin/ directory
make install # installs binaries to /usr/local/bin
# PREFIX=/some/other/path make install installs to /some/other/path
brew install macpine or manually via brew install qemu.aarch64 instances on boot when using vmnet networking (see Troubleshooting). If you hit this, pin QEMU to 10.0.3 until it's fixed upstream.vmnet) networking require sudo for alpine start/stop/ssh/exec, unless socket_vmnet is installed and running.sudoBy default, vmnet networking (a real, LAN-reachable IP for the instance) requires root, because QEMU calls macOS's Vmnet.framework directly. Installing socket_vmnet removes that requirement: it does the one privileged step once, in the background, and macpine talks to it over a Unix socket instead.
brew install socket_vmnet
sudo brew services start socket_vmnet # one-time; runs persistently in the background
macpine detects a running socket_vmnet daemon automatically. If it isn't found, macpine transparently falls back to QEMU's native vmnet-shared networking (requiring sudo, as before).
To create and start a new instance:
alpine launch # launches with default parameters
alpine launch -a aarch64 # create an aarch64 instance
alpine launch -d 10G -c 4 -m 2048 # create an instance with a 10GB disk, 4 cpus, and 2GB of RAM
alpine launch -h # view all configuration options and defaults
Access instance via ssh:
alpine launch -s 22 # launch an instance and expose SSH port to host port 22
alpine ssh instance-name # attach shell to instance (replace `instance-name` as appropriate)
Expose additional instance ports to host:
# launch an instance, expose SSH to host port 2022 and forward host ports 8888 and 5432 to instance ports 8888 and 5432
alpine launch -s 2022 -p 8888,5432
# launch an instance, expose SSH to host port 8022, forward host port 8081 to instance port 8082, and forward
# host port 8083 to instance port 8083
alpine launch -s 8022 -p 8081:8082,8083
# launch an instance, expose SSH to host port 9022, forward host port 9091 UDP to instance port 9091 UDP,
# and forward host port 9092 UDP to instance port 9093 UDP
alpine launch -s 9023 -p 9091u,9092:9093u
Instances can be easily packaged for backup or sharing as .tar.gz files:
alpine list
NAME STATUS SSH PORTS ARCH PID TAGS
cheerful-result Running 2022 aarch64 26568
glittering-swing Running 3022 x86_64 57206 emulation,intel
alpine publish cheerful-result
This will create a file cheerful-result.tar.gz which can be imported as:
#alpine delete cheerful-result
alpine import cheerful-result.tar.gz
See all the docs for more information:
Create, control, and connect to Alpine instances.
Usage:
alpine [command]
Available Commands:
completion Generate shell autocompletions.
delete Delete instances.
edit Edit instance configurations.
exec execute a command on an instance over ssh.
help Help about any command
import Imports an instance archived with `alpine publish`.
info Display information about instances.
launch Create and start an instance.
list List instances.
pause Pause instances.
publish Publish instances.
rename Rename an instance.
restart Stop and start instances.
resume Unpause instances.
ssh Attach an interactive shell to an instance via ssh.
start Start instances.
stop Stop instances.
tag Add or remove tags from an instance.
Flags:
-h, --help help for alpine
Use "alpine [command] --help" for more information about a command.
Multiple instances in a command: some commands (delete, edit, info, pause, publish, restart, resume, start, stop)
accept multiple instance names and will repeat the operation over each unique named instance once.
Tags: using alpine tag, instances can be tagged; tags can be used in multi-instance commands (see above) e.g.
alpine start +foobar will start all instances which have had been tagged foobar with alpine tag instance-name foobar. Note that
the tag launchctl-autostart is used for auto-starting instances at login.
Shell autocompletion: shell command completion files (installed automatically with brew install macpine) can be generated with
alpine completion [bash|zsh|fish|powershell]. See alpine completion -h or the completion documentation
for more information.
1,338 followers · starred Apr 2024
9,478 followers · starred Nov 2022
5,204 followers · starred Sep 2025
4,328 followers · starred Nov 2022