An alternative Docker installation with Multipass on macOS without using Docker for Mac
5 min read
1276 words
Last week I received an email from the Docker Team which said that Docker for Mac (the software which also comes with a GUI) will be forbidden for commercial use when the company has more than 250 employees AND makes more than $10 million per year. To use it commercially the company has to get licenses for every developer using it, starting at $5/month. This made me think what an alternative could be for devs that don’t want to use Docker for Mac anymore, since I read a lot of posts that many devs don’t even need it. Most of them interact via CLI anyway.
I stumbled across a nice article from Josh Gorneau where he uses multipass to host his Docker VM. In this case, it is a Ubuntu 20.04 installation. So a couple of commands will be similar to Josh’s article such as the VM configuration used in this post. So let’s start with setting up multipass.
Install Multipass
Multipass is a project made available by Canonical[1] also develops and publish the Ubuntu[2] Linux distribution. So install it either from the website or via homebrew. If you don’t have the Docker CLI yet, install it too
brew install multipass docker
Creating an SSH Key
Since we will connect to our VM via SSH we need a new SSH key that will be
imported while setting up the VM. To do so we can use ssh-keygen
like in the
following. I will create a new one since I use just one for every service I
connect to. Follow the prompts to generate a key. Mine will be called
docker-multipass
. Since macOS and Ubuntu are pretty similar in creating SSH
keys you can also follow the instructions over at
DigitalOcean.
➜ ~ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/user/.ssh/id_rsa): /Users/user/.ssh/docker-multipass
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/user/.ssh/docker-multipass.
Your public key has been saved in /Users/user/.ssh/docker-multipass.pub.
The key fingerprint is:
SHA256:LjhUL0bZ8lXf9iIrOPF1EXjAJguNu3YbvUVH2tUHcak user@domain
The key's randomart image is:
+---[RSA 3072]----+
| o .oo+o+|
| oo o.+..==|
| = .o.+ .++=|
| o +... Eoo+|
| . o S. .o.o..|
| . o oo+o..+.. |
| o ..+.oo.o |
| . . .... |
| |
+----[SHA256]-----+
To get the generated public key which will be imported to the Ubuntu VM on the
setup you can use cat /Users/user/.ssh/docker-multipass.pub
. Copy the output
since you will need it in the next step.
The VM Config
In the following, we will create a config that will be used to set up the VM. This is done with a cloud-init configuration. Cloud-init[3] is a configuration tool from Ubuntu that helps set up virtual machines. More Information about it can be found here: Using cloud-init with Multipass | Ubuntu. The config is taken from Josh’s article linked above.
Create a docker.yaml
file in your current directory and paste in the following
configuration:
---
users:
- name: ubuntu
sudo: ALL=(ALL) NOPASSWD:ALL
ssh-authorized-keys:
- ssh-rsa AAAAB3...
package_update: true
packages:
- docker.io
- avahi-daemon
- apt-transport-https
- ca-certificates
- curl
- gnupg
- lsb-release
runcmd:
- sudo curl -fsSL https://get.docker.com | sudo bash
- sudo systemctl enable docker
- sudo systemctl enable -s HUP ssh
- sudo groupadd docker
- sudo usermod -aG docker ubuntu
The configuration sections explained
users
is an Array that defines what users should be set up while creating the VM. Here you will also paste your SSH key created in the last step.package_update
tells the Ubuntu VM to runapt-get update
before installing any packages in the following step to make sure the newest packages are available for installationpackages
as the name suggests tells Ubuntu which packages to install to proceedruncmd
will be run after installing the packages before. In this case, it will download Docker, enabling it via systemctl, creating the docker group and afterwards adding our newly created user to this group. This will make sure that our ubuntu is allowed to interact with Docker.
Launching the Ubuntu VM
multipass launch -c 4 -m 8G -d 20G -n docker 20.04 --cloud-init docker.yaml
-c
this specifies how many CPUs the VM can use. In this case 4-m
defines the amount of RAM-d
is for setting the disk space used by the VM-n
sets the VM’s name
Handling possible permission problems with a non-root user
launch failed: multipass socket access denied
Please check that you have read/write permissions to '/var/run/multipass_socket'
When you use a macOS user which is not a local admin like I do you have to give
this user the permissions to read/write to multipass’s socket to be able to
function. So use the chmod
command to give your user the permissions needed.
Otherwise, you will not be able to start multipass instances.
sudo chmod a+rw /var/run/multipass_socket
After that, the socket should be usable for the non-root user.
Log into VM
After launching the multipass Ubuntu VM in the last step check if it is possible to ssh into the newly created VM.
ssh ubuntu@docker.local
Permission denied (publickey)
When the error ubuntu@docker.local: Permission denied (publickey).
will be
thrown check if you provide the right ssh key when connecting. Without
specifying a key ssh will use your main ssh key which is most often id_rsa
.
To use the key created above add an entry to your .ssh/config
like below.
Host docker.local
HostName docker.local
User ubuntu
IdentityFile ~/.ssh/docker-multipass
If you can connect to your newly created VM close the connection with exit
and
proceed to the next step where we will now use Docker from our host machine to
interact with the Docker installed in the virtual machine.
Time to use Docker
Now that everything is set up check if Docker is answering. Since we use a
custom Docker host we have to provide the cli where we want to execute the
commands. This is where DOCKER_HOST
comes into play, so use it like in the
example below.
DOCKER_HOST="ssh://ubuntu@docker.local" docker version
Save the Docker Host environment variable in your terminal session
Since always putting the DOCKER_HOST
variable in front of the commands can be
annoying you can export it in your terminal session or save it in your .bashrc
or .zshrc
to have it in every terminal session in the future.
export DOCKER_HOST="ssh://ubuntu@docker.local"
Have fun using Docker
When everything is set up and your Docker is usable from within your terminal you can now start any container you like.
docker run -p 9898:9898 stefanprodan/podinfo
Exposing Ports to the Host machine
Right now (January 22) multipass does not automatically port-forward the exposed
ports from within the VM. To set this up for a port use ssh with the -L
argument which will block the port on your host machine which is exposed on the
connected machine.
ssh -L <Host-Port>:localhost:<VM-Port> ubuntu@docker.local
I hope this article helped you set up and use Docker without using the Docker for Mac software.
Thank you for reading,
Niklas