How to Replace Docker Desktop with Ubuntu Multipass

How to Replace Docker Desktop with Ubuntu Multipass

When Docker decided to change the Docker Desktop pricing model I found that, while reasonable, it was an additional reoccurring cost for basic tooling that remained easily accessible and free on other platforms so I set on a search for alternatives.

Ubuntu Multipass is one of numerous alternatives that can replace Docker Desktop on Macs and Windows.

Getting Started

The following steps have been tested on an Intel Macbook w/ 16gb of ram after removing Docker Desktop.

Installing Multipass

Ideally, use brew install multipass, however there’s currently a bug (sftp server: handle_stat: cannot stat #2203) which results in log files filling your hard drive. As of time of writing it is recommended to use the package referenced in the issue.

Configuring a Shell

The following configuration values can be modified, but those presented have been tested successfully with a large application stack. Additionally, changing the shell name will require changes to commands that follow in this guide.

multipass launch --name development --cpus 4 --mem 8g --disk 100G

Entering the Shell

multipass shell development

All command from this point forward, unless specified otherwise, are to be done from within the multipass shell.

Installing Docker

curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
sudo apt install docker-compose

Optionally, Configure Sudoless Docker

sudo apt-get install -y uidmap
dockerd-rootless-setuptool.sh install
echo "export DOCKER_HOST=unix:///run/user/1000/docker.sock" >> ~/.bashrc
source ~/.bashrc

Optionally, Configure AWS

sudo apt install awscli
aws configure
$(aws ecr get-login --no-include-email --region us-west-2)

Probably, Configure GitHub

git config --global user.email "you@example.com"
git config --global user.name "Your Name"
ssh-keygen -t ed25519 -C "your_email@example.com"
cat ~/.ssh/id_ed25519.pub

You can add the new key here: SSH and GPG keys.

Maybe, Transfer Existing Source Code

It may be more or less work to transfer your existing code as there will be configuration differences between Mac and Linux. It’s also possible to run off the mount, but you may experience high cpu usage depending on the application’s disk activities.

On the Mac:

multipass mount ~/git/ development:/home/ubuntu/git-mac/

In the Multipass shell:

cp -Rv git-mac/ git

On the Mac:

multipass umount development

Optionally, Configure Privileged Port Access in the Virtual Machine

While Docker is perfectly happy trying to bind to any port, the Ubuntu install needs some coaxing:

echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee -a /etc/sysctl.conf
sudo sysctl --system

You can now start as containers as usual: docker-compose up

As needed, Configure Additionally Software

If you plan to run some things in the container without docker, you may need some extra tools, e.g.:

sudo apt install npm

If you’ve transfered source code, the stored configuration may have environment specific tools which need cleared. For example the package-lock.json should not be checked in from Linux until you’ve standardized, or it could break Mac installations and the node_modules should be re-installed.

rm -r ./node_modulesrm package-lock.json
npm install

You can now start non-docker projects as well, e.g. npm start

Finding IP Addresses

Routing could have some new complexity now that the stack has changed. Finding the right IP addresses could pose some challenges. Tinkering will be required, here are some tips.

To see the IP addresses, and other information on the running virtual machines:

multipass info --all

And on the mac:

ifconfig

In some instances, host.docker.internal and the magic host-gateway could be useful in your docker-compose.yml files:

version: '3'
services:
nginx:
extra_hosts:
host.docker.internal: host-gateway

For trickier bits, an environment variable set from .env could be useful; more info here: Environment Variables in Compose

version: '3'
services:
nginx:
environment:
- ENV_SOME_HOST=${ENV_SOME_HOST}

A set of example docker-compose.override.yml files could be useful to store in your repositories as there will likely be differences as staff settle on different solutions.

SSH

Since your essentially running virtual machines, you can even setup network access.

In the multipass shell:

sudo adduser someuser
sudo vi /etc/ssh/sshd_config

Ensure settings PasswordAuthentication yes and PermitEmptyPasswords no are set.

Restart:

sudo /etc/init.d/ssh restart

Now you can ssh in from the mac:

ssh someuser@your-vm-ip

Further Reading

Without the obfuscation of the virtual machine, tools like ansible can now be used on top of multipass or ssh to provison new environments with reusable runbooks. Ansible for DevOps: Server and configuration management for humans would be an great read on that topic. Additionally, it’s assumed the reader has familiarity with Linux considering the pre-existing knowledge from Docker, but to learn more about Ubuntu I’d suggest picking up Ubuntu Linux Unleashed.

Conclusion

While Docker Desktop is very convenient, Ubuntu Multipass is likely an upgrade and a swiss army knife for development. The multipass command can be used to run any number of Linux instances, which can run docker images and other applications or development environments on a Mac. You can even expose a full desktop and access it via remote desktop if you are brave enough. While that’s cool, a great side effect is that each instance is stored in an image file, which can be pre-configured and shared to new and existing engineers.

Back to blog

Leave a comment

Please note, comments need to be approved before they are published.