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.
Multipass is a project made available by Canonical also develops and publish the Ubuntu 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
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.
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 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.
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
usersis 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_updatetells the Ubuntu VM to run
apt-get updatebefore installing any packages in the following step to make sure the newest packages are available for installation
packagesas the name suggests tells Ubuntu which packages to install to proceed
runcmdwill 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.
multipass launch -c 4 -m 8G -d 20G -n docker 20.04 --cloud-init docker.yaml
-cthis specifies how many CPUs the VM can use. In this case 4
-mdefines the amount of RAM
-dis for setting the disk space used by the VM
-nsets the VM’s name
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.
After launching the multipass Ubuntu VM in the last step check if it is possible to ssh into the newly created VM.
When the error
email@example.com: 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.
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://firstname.lastname@example.org" docker version
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
.zshrc to have it in every terminal session in the future.
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
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> email@example.com
I hope this article helped you set up and use Docker without using the Docker for Mac software.
Thank you for reading,