Running containers on a Mac

Irfan Ali Shaik
5 min readFeb 19, 2022

What is a container ?

A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another.

More details What is a Container? | App Containerization | Docker

The first name that comes to us when we hear about containers in docker.

And docker comes up with our product called Docker Desktop, which has a nice GUI, very easy to use and comes with lots of features.

The tool can be downloaded form official site and the installation in straight forward.

From January 31, 2022 ,

Docker Desktop can be used for free as part of a Docker Personal subscription for: small companies (fewer than 250 employees AND less than $10 million in annual revenue), personal use, education, and non-commercial open source projects.

More details here

Started looking at alternative options for running containers and came across 2 options

  1. Podman
  2. Vagrant with virtual box

Podman

Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System.

The Mac client is available through Homebrew:

brew install podman

You can then verify the installation information using:

podman info

To start the Podman-managed VM:

podman machine init
podman machine start

Podman commands are fully compatible with Docker, so you can replace one with the other: alias docker=podman.

More details here

If you use docker-compose , there is an alternative for this podman-compose

The installation is simple. Install python if don’t have and then install podman-compose.

brew install python@3.10pip3 install podman-compose

Podman with combination of podman-compose works perfectly fine.

Have issues with local volumes. which some want. For example persisting database data.

But, podman 4 is coming up soon with lots of exiting features which includes options for using local volumes. Looking forward to try it out

Vagrant with virtual box

While looking at this old way of doing before the before we had docker desktop, came across an excellent post Run Docker without Docker Desktop on macOS | Dhwaneet Bhatt on the same.

Had to do minor changes to the recipe provided in the blog to make it work.

Create a script file . eg : vagrant_docker_setup.sh and copy the contents of the file

# Install VirtualBoxbrew install --cask virtualboxbrew install --cask virtualbox-extension-pack# Install Vagrant and the vbguest plugin to manage VirtualBox Guest Additions on the VMbrew install vagrantvagrant plugin install vagrant-vbguest# Install Docker CLIbrew install dockerbrew install docker-compose
mkdir vagrant-docker-engine
cd vagrant-docker-engineecho \"Vagrant.configure('2') do |config|config.vm.box = 'ubuntu/focal64'config.vm.hostname = 'docker.local'config.vm.synced_folder "/Users/irfan/docker_data", "/vagrant", type: "rsync"config.vm.network 'private_network', ip: '192.168.56.4'config.vm.network 'forwarded_port', guest: 2375, host: 2375, id: 'dockerd'config.vm.provider 'virtualbox' do |vb|vb.name = 'ubuntu-docker'vb.memory = '2048'vb.cpus = '2'endconfig.vm.provision 'shell', path: 'provision.sh'# Configuration for Port Forwarding# Uncomment or add new ones here as required#config.vm.network 'forwarded_port', guest: 6379, host: 6379, id: 'redis-server'#config.vm.network 'forwarded_port', guest: 5432, host: 5432, id: 'postgres-server'#config.vm.network 'forwarded_port', guest: 3306, host: 3306, id: 'mysql-server'end" | tee Vagrantfile > /dev/nullecho \"# Install Dockerapt-get remove docker docker-engine docker.io containerd runcapt-get updateapt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release net-tools software-properties-commoncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpgecho 'deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu focal stable' | tee /etc/apt/sources.list.d/docker.list > /dev/nullapt-get updateapt-get install -y docker-ce docker-ce-cli containerd.io# Configure Docker to listen on a TCP socketmkdir /etc/systemd/system/docker.service.decho \\'[Service]ExecStart=ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock' | tee /etc/systemd/system/docker.service.d/docker.conf > /dev/nullecho \\'{\"hosts\": [\"fd://\", \"tcp://0.0.0.0:2375\"]}' | tee /etc/docker/daemon.json > /dev/nullsystemctl daemon-reloadsystemctl restart docker.service" | tee provision.sh > /dev/nullchmod +x provision.sh

Update the folder to you local folder to sync. ( volumes)

config.vm.synced_folder

To start the virtual vm

vagrant up

You may encounter an error with IP address.

The IP address configured for the host-only network is not within the
allowed ranges. Please update the address used to be within the allowed
ranges and run the command again. Address: 192.168.56.4
Ranges: 192.168.xx.0/21

In such case update “config.vm.network” and re run it .

You can remove the installation part if re run needed.

Once the VM is up and running.

# Save IP to a hostname
echo "192.168.66.4 docker.local" | sudo tee -a /etc/hosts > /dev/null

# Tell Docker CLI to talk to the VM
export DOCKER_HOST=tcp://docker.local:2375

Use the same IP as used in script.

In the vagrant file created, we can add more ports to forward

# Uncomment or add new ones here as required#config.vm.network 'forwarded_port', guest: 6379, host: 6379, id: 'redis-server'

You can forward any port you can like 8080 etc for you applications. Else you need use docker.local instead of localhost

Vagrant Cheatsheet

vagrant suspend - stop the VM for saving system resources. This does not delete any data. Just run vagrant up to spin up the VM.

vagrant reload - for reloading the VM for any changes made to the config e.g. adding a new port mapping.

vagrant delete - This deletes the VM with all the data. All mapped volumes will be lost. Know what you're doing before running this. If you just want to stop the VM use vagrant suspend.

For every port that we want to natively access on macOS host, we need to modify the Vagrantfile to add port forwarding. Use vagrant reload after changing the file. Some examples have already been provided in the Vagrantfile for reference.

If you use intelliJ , we can see our containers logs easily

  1. Press ⌘ , to open the IDE settings and select Build, Execution, Deployment | Docker.
  2. Click + to add a Docker configuration.
  3. Select TCP socket and specify the Docker API service URL in Engine API URL: tcp://localhost:2375.
  1. If everything is correct, you should see Connection successful at the bottom of the page. Else check if the VM is running or suspended.
  2. Double-click the configured Docker connection in the Services tool window (View | Tool Windows | Services or ⌘ 8).

Similarly we can run podman too inside our vm as described in Podman | IntelliJ IDEA (jetbrains.com)

You can also take a look at

minikube start | minikube (k8s.io)

Rancher Desktop

Happy Learning

--

--