Running a container with the Docker blueprint in Multipass

Errors or typos? Topics missing? Hard to read? Let us know or open an issue on GitHub.

Key Value
Summary Running a Docker Container in Multipass
Categories multipass
Difficulty 2
Author nathan.hart@canonical.com

Overview

Multipass has a Docker blueprint that gives its users access to out-of-the-box Docker on any platform. This new blueprint makes it easy to develop and test Docker containers locally on macOS, Windows, or Linux.

In this tutorial, we will see how to get started with the Docker blueprint by creating a blog in a Docker container in Multipass.

What we’ll learn

  • How to use Docker on macOS or Windows with Multipass

  • How to alias the docker command to our host command line

  • How to use Portainer to launch a Docker container in Multipass

What we’ll need

  • Any computer with an internet connection

Install Multipass

Duration: 3 minutes

We’ll start by installing Multipass on our machine as shown here. Simply click on the operating system and follow the instructions.

Launch a Docker VM

Duration: 1 minute

Now that Multipass is installed, we can create a VM running Docker very simply. Open up a terminal and type

multipass launch docker

This command will create a virtual machine running the latest version of Ubuntu, with Docker and Portainer installed. We can now use Docker already! Try the command below to see for yourself!

multipass exec docker docker

Alias of the Docker commands

Duration: 1 minute

The Docker blueprint creates automatically two aliases, that is, two commands which can be run from the host to use commands in the instance as if they were in the host. In particular, the host docker command executes docker in the instance, and the host docker-compose command executes docker-compose in the instance.

In order for these to work, we just need to add them to the path so that we can use them directly from our command line. If this was not done before, launching the Docker blueprint will return instructions showing how to add the aliases to our path. Simply copy and paste the command shown. It will likely be of this form:

PATH="$PATH:/home/<user>/snap/multipass/common/bin"

$ multipass launch docker
You'll need to add this to your shell configuration (.bashrc, .zshrc or so) for
aliases to work without prefixing with `multipass`:

PATH="$PATH:/home/nhart/snap/multipass/common/bin"

We can now use docker straight from the command line. To try it out, run

docker run hello-world

Using Portainer

Duration: 5 minutes

We’ll now go one step further, with Portainer. The Docker blueprint comes with Portainer installed, which gives an easy-to-use graphical interface for managing our Docker containers. To access Portainer, we will first need its IP address. The following command will show the IP addresses associated with the Ddocker VM we created in the previous steps:

multipass list

There should be two IP addresses listed, one for the Docker instance, the other for Portainer. The Portainer IP should start with a 10.

In a web browser, enter the Portainer IP address from the previous step followed by the Portainer port, 9000, like this: “:9000”. Set up a username and password at the prompt, then select the option for managing a local Docker environment and click connect.

Click on the newly created “Local” environment to manage the Docker instance on our local VM.

Launching a container

Duration: 5 minutes

For this tutorial, we will be creating a blog using the Ghost template in Portainer. Portainer has many other app templates if you are looking for more ideas. If you want more selection, you can launch containers from the Docker hub from Portainer or from the command line.

Inside Portainer, click on App Templates in the left toolbar, and scroll down to the Ghost template.

Now, we can configure and deploy the template. Enter a name and click deploy. The bridge network is the default and correct option.

On the Containers page, we should now see two containers running. One containing Ghost, and the other containing Portainer itself.

We can now access our Ghost blog by going to the published port indicated in the Containers page, i.e., <VM IP Address>:<Ghost Port>.

There it is, our blog running within a Docker container inside Multipass!

For next steps, try out Portainer’s other App Templates (Step 5), or check out Docker Hub for more containers to try. If you want to try out container orchestration, Microk8s or Multipass’ Minikube blueprint are great places to start.

2 Likes

Can you provide a diagram for the Docker workflow, please?
Many thanks.

Hi @llivadas1, welcome and thanks for the comment! I put together a diagram of what this tutorial will create here.

Not sure if this is the right place or not, but I spent too long figuring out how to add path variable for macos - it changed with the introduction of path_helper and makes the docker install much easier https://www.softec.lu/site/DevelopersCorner/MasteringThePathHelper

1 Like

My Ghost container starts, then immediately stops with this error:

[2023-04-26 09:09:45] INFO Ghost is running in production...
[2023-04-26 09:09:45] INFO Your site is now available on http://localhost:2368/
[2023-04-26 09:09:45] INFO Ctrl+C to shut down
[2023-04-26 09:09:45] INFO Ghost server started in 1.151s
[2023-04-26 09:09:45] ERROR connect ECONNREFUSED 127.0.0.1:3306
connect ECONNREFUSED 127.0.0.1:3306
"Unknown database error"
Error ID:
    500
Error Code:
    ECONNREFUSED

I did get an Apache httpd container running ok though.

Update: googling the error I find that latest Ghost has moved from sqlite3 to mysql hence the error. This blog post [1] explains how to set env vars when starting container so that Ghost will use sqlite3. Also I found that you have to add container ‘manually’ rather than use the Portainer template otherwise you do not get access to the env var settings. Doing this, I got Ghost running as per your blog.

[1]https://www.maroonmed.com/make-sqlite-work-again-with-ghost-5-on-docker/

1 Like

Thanks for this update! I’ll look into updating this to use a less finicky container.

I’m not sure if this is recent but the main link to the guide has all images broken (even when trying on separate browser and devices using permalinks), hard to follow the steps, could it be a permission issue in your google repo?

Hi @unosomoroso, thank you pointing this out! We’ll follow up and get those fixed.

It should be better now. Thanks again for letting us know @unosomoroso.

working like a charm @ricab!!! thank you for fixing it so quickly!

1 Like

Not sure why, but the docker template doesn’ t output path information on macOS. I found the right folder to add, but wasn’t sure if that was something that should be added/fixed.

It is $HOME/Application Support/multipass/bin for anyone else who is confused.

Hi @zchrykng, thanks for your comment. The message with the folder to add is shown only once, when creating an instance which contains aliases (like the Docker example) or aliasing a command on a given instance. If that message was never shown, then there is a bug somewhere. If this is the case, please enumerate the commands you issued so we can reproduce and investigate the bug. Thanks!

So, most of this is not relavent, but figured I’d include it for completeness. At no point did this show a prompt with the required folder/information.

1405  2024-01-18 09:15  brew install multipass
1406  2024-01-18 09:16  /var/folders/x9/sdvyzrms22q93v8fn9s5l21w0000gn/T/multipass-gui.bsSBEk.command ; exit;
1407  2024-01-18 09:21  brew install duti
1408  2024-01-18 09:22  mdls /Applications/iTerm.app/ | grep BundleIdentifier
1409  2024-01-18 09:22  duti -s com.googlecode.iTerm2 com.apple.terminal.shell-script shell
1410  2024-01-18 09:22  /private/var/folders/x9/sdvyzrms22q93v8fn9s5l21w0000gn/T/multipass-gui.zLQexv.command; exit
1411  2024-01-18 09:28  multipass launch docker

Thanks! What terminal are you using, the default one? What shell (for example, bash, zsh, …)? It will not output if using a non-interactive shell.

I’m using iTerm and zsh. zsh is the default in macOS now. iTerm is not the default, at least it wasn’t before this. And I was using it interactively.

Great, can you please send me the output of this command on your terminal?

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
~
❯ [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
Interactive

OK, so the terminal and shell are not the issue. Are you sure your PATH variable does not contain the folder? The message won’t be shown in that case.

Hi @zchrykng! We finally found the issue. It is being fixed here. Thanks a lot for reporting and investigating!