Docker is great for quickly dropping into a Linux environment, but isn't compatible with certain obscure use cases (mine being testing version-locked Java GUIs).
After a period of unsuccessfully installing random packages and toggling flags, I figured the next-easiest thing to do was to use VirtualBox. Perhaps surprisingly, it comes with an able CLI. Here's how it compares to Docker's.
brew install --cask virtualbox
There's no equivalent of
docker run -it to start a VM and give me a shell; we'll have to use
We import the image, the equivalent of
docker load. This takes about a minute, for a 4GB image.
vboxmanage import vm.ova # `vm` from now on is the name of our virtual machine, which we can confirm with vboxmanage list vms # port forward, so we can use ssh. the first port is the host's vboxmanage modifyvm vm --natpf1 "ssh,tcp,,2222,,22" # power it on vboxmanage startvm vm vboxmanage startvm vm --type headless # now it appears here vboxmanage list runningvms # wait for the VM to start, then ssh -p 2222 email@example.com
At this point we can interactively get the VM into the state we want, or write a script to automate it. The subcommand for the latter is
guestcontrol, similar to
vboxmanage guestcontrol vm run /bin/sh --username user --password pass --verbose --wait-stdout --wait-stderr -- -c "echo test"
The docs say that stdin is forwarded, but it seems signals aren't, so I couldn't get a piped shell script to run. We can work around that somewhat with the
guestcontrol copyto subcommand.
vboxmanage guestcontrol vm copyto --verbose --username user --password pass host-dir --target-directory /home/vm
When we're done, we'll want to power the VM off, export the new state back to an ova file if necessary, then delete it.
vboxmanage controlvm vm poweroff vboxmanage export vm -o vm1.ova vboxmanage unregistervm vm --delete
Mounted Volumes (aka Shared Folders)
I don't actually remember what the Guest Additions CD contributes to this, but it seems we don't need it here.
First, we tell VirtualBox about the shared folder. We'll have to power off for this.
vboxmanage sharedfolder add vm --name share --hostpath ~/Downloads/shared # we see it here vboxmanage showvminfo vm
Inside the VM, we get to pick where we want to mount the shared folder.
# create the directory we want to mount at mkdir /home/user/shared # add ourselves to the vboxsf group sudo usermod -a -G vboxsf user sudo mount -t vboxsf -o uid=$(id -u),gid=$(id -g),rw share /home/user/shared
Powering the VM off unmounts the shared folder, but we can also do it manually.
sudo umount /home/user/shared
vboxmanage snapshot vm list vboxmanage snapshot vm take s vboxmanage snapshot vm restore s vboxmanage snapshot vm delete s
Certainly not as easy as Docker, but it's FOSS and easy enough to automate. It's a great alternative if you just can't get Docker to work or need more isolation or reproducibility.