Docker CLI has cemented its place as the tool of choice for developers to manage containers programatically. The 2022 Docker Community Survey found 72% of respondents actively using Docker CLI pointing to its relevance even with the availability of graphical interfaces.

However, the default method of accessing docker CLI requires installing the Docker Desktop app on Mac which is resource heavy. This article provides expert techniques to harness the power of Docker CLI on Mac conveniently without needing the heavier Docker Desktop, relying instead on minikube for the Docker engine requirements.

Docker CLI Usage Stats

Docker survey showing wide adoption of CLI vs GUI

Why Use Docker CLI Without Desktop

Here are some motivations to access Docker CLI directly instead of the desktop app:

1. Avoid Heavy Resource Usage

Docker Desktop runs its own embedded Linux VM with docker engine to power the containers. This consumes significant CPU, memory, disk and battery resource even when not actively working with containers.

In contrast, docker CLI coupled with minikube has near zero resource overhead when not in use.

2. Preserve Battery Life

Related to above, not needing Desktop improves laptop battery lifespan when on the move. The native CLI workflow maximizes longevity without eating battery cycling out VMs continuously.

3. Leverage Native Toolchains

Docker CLI combined with Kubernetes CLIs like kubectl provide the most idiomatic experience on Mac to manage containers and clusters. No need for translations through Desktop app abstractions.

4. Enables Automation

CLI is indispensable for CI/CD automation. Direct docker CLI on Mac facilitates developing automated scripts triggering Docker builds or Infrastructure-as-Code flows before promoting to downstream environments.

5. Flexible Deployment Options

The CLI approach gives flexibility to deploy containers either locally via minikube or push to cloud platforms like AWS ECS/EKS without vendor lock-ins imposed by Desktop integration.

Prerequisites for Docker CLI

Check if your Mac meets the prerequisites before installing docker CLI:

  • Hardware: Mac hardware must be a 2010 or newer model with Intel VT-x support.
  • OS Version: MacOS 10.11 (El Capitan) or higher.
  • Homebrew: Latest Homebrew package manager.

You can verify the prerequisites easily through About This Mac dialog accessible from the Apple menu. Most modern Mac devices should meet the criteria.

MacOS Version Dialog

Install Docker CLI Using Homebrew

Homebrew is the recommended package manager for installing various CLI tools on Mac. Once Homebrew is installed, use it to get docker CLI:

brew install docker 

Homebrew will install the latest stable Docker release including the containerd runtime.

You can also install a specific version by appending it:

brew install docker@20.10.8

Some key components installed:

  • docker: The docker CLI client itself
  • containerd: Container runtime process manager
  • runc: Low-level container runtime binary
  • Docker plugins: CLI extensions for added functionality

Additionally install Docker Compose which helps running multi-service apps:

brew install docker-compose 

Confirm docker and compose versions:

docker --version
docker-compose --version

With the CLI tools installed next is the runtime environment via minikube.

Minikube Architecture for Docker CLI

The docker CLI requires an active Docker daemon to operate. In Desktop deployment, this is provided by the embedded Linux VM running docker engine.

The open source minikube tool eliminates needing the heavy VM by providing a light-weight single node Kubernetes cluster with an integrated docker runtime.

Minikube Architecture

Minikube clusters run Docker & Kubernetes in a tiny VM on Mac

Here is how minikube enables docker CLI accessibility on Mac:

  • Minikube provisions a Linux VM using drivers like Hyperkit or VirtualBox on Mac. This hosts Docker daemon.
  • Kubeadm bootstraps an easy Kubernetes cluster pointing to the Docker engine.
  • CLI communicates with the Docker daemon inside the minikube VM via environment variable mappings.
  • Host ports directly map to VM ports allowing seamless docker access from CLI.
  • Containers run nested on the VM layered on top of Kubernetes rather than on bare metal.

Now with background on minikube, let‘s run it.

Start Minikube Cluster

minikube start

On first run, minikube will:

  • Set up the Hyperkit VM and associated networking.
  • Download VM boot images.
  • Install kubeadm tooling inside the VM.
  • Initialize Kubernetes control plane components like API server.
  • Configure node services – Docker, kubelet etc.

Be patient as this can take 5-10 mins depending on internet bandwidth. Subsequently this is cached so comes up quickly.

You can track live progress in another terminal with:

minikube logs -f

Verify minikube status once done:

minikube status

🟢 minikube: Running
🟢 PROFILE: minikube
🟢 Kubernetes: v1.25.2 ...
🟢 CONTAINER-RUNTIME: docker://24.3.0

Ensure the Container Runtime points to active docker.

Connect Docker CLI to Minikube

By default, docker CLI communicates with the host Docker daemon which won‘t be available here.

Tell docker CLI to connect to the docker instance inside the minikube VM:

eval $(minikube docker-env) 

Behind the scenes this sets environment variables like DOCKER_HOST to direct CLI requests internally within VM instead of externally.

 env | grep DOCKER

DOCKER_HOST=tcp://192.168.64.2:2376
DOCKER_CERT_PATH=/Users/myuser/.minikube/certs
DOCKER_API_VERSION=1.41
DOCKER_DEFAULT_PLATFORM=linux/amd64
DOCKER_TLS_VERIFY=1

Notice how certificates and API communication parameters are auto-configured to securely speak to minikube‘s docker.

Add Minikube IP to Hosts

While CLI is correctly mapped to internal Docker instance, image names need resolving:

$ docker pull nginx
Unable to find image ‘nginx:latest‘ locally

To make this seamless, add minikube‘s VM IP to Mac‘s hosts file:

echo "$(minikube ip) docker.local" | sudo tee -a /etc/hosts

# 192.168.64.2 docker.local

Here docker.local acts as an alias for minikube IP to avoid repeating long IP addresses.

Now nginx will correctly resolve by talking to the Docker registry inside the minikube VM and not externally to Docker Hub.

Test Docker Setup

Your docker CLI is ready for action!

Run the ubiquitous hello-world image:

docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly...
. . .

This validates the CLI installation by:

  • Pulling the image from minikube registry into VM.
  • Creating a container from that image within VM.
  • Executing the containerized process and capturing output.
  • Streaming the output over CLI stdout.

Likewise, you can build images, run databases like MongoDB or spin up an application stack with docker compose!

Docker Desktop vs Docker CLI + Minikube

Here‘s a comparative look at the docker CLI experience between Docker Desktop and minikube:

Feature Docker Desktop Docker CLI + Minikube
Installation Heavyweight macOS app Lean Homebrew CLIs
System Resources High memory + CPU Near zero overhead
Docker Engine Embedded Linux VM Within minikube VM
Kubernetes Support Inbuilt managed cluster Lightweight local cluster
Networking Separate space via Hyperkit Forwarded ports
Storage Filesharing mechanisms Minikube managed volumes
Compose Support Native app compose Via CLI with overrides
Pricing Free personal use 100% Open source

For developers getting started, minikube provides a nimble environment to learn Docker and Kubernetes concepts before scaling up.

Best Practices for Optimized Workflow

Here are some tips for an efficient developer workflow leveraging Docker CLI:

  • Use image tags beyond latest for predictable builds. For example, node:18.12.1-alpine.
  • Employ .dockerignore to exclude non-essential files copying into images.
  • Leverage multi-stage docker builds to minimize final image sizes.
  • Define environment-specific configurations via docker ENV variables instead of baking them into images.
  • Reuse volumes for stateful data instead of containers for durability.
  • Use docker manifests and multi-arch images for supporting multiple platforms through a single image/tag.
  • Familiarize with network primitives like bridges, overlays and service discovery for multi-service communication.
  • Follow container healthcheck conventions for maximum service resilience.
  • Consider multi-node Kubernetes cluster options like Kind or k3s once comfortable with local workflows.

Adopting these best practices will accelerate leveraging docker CLI in a cloud-native way.

Modern Docker CLI Capabilities

Latest docker releases expand CLI capabilities further through:

1. BuildKit Backend:

The BuildKit engine modernizes image building functionality by enabling:

  • Faster build parallelization
  • Incremental rebuilds
  • Dynamic nodeless builds
  • Concurrent system resource usage
  • Security isolation plugins

Activate the BuildKit backend via:

export DOCKER_BUILDKIT=1

2. Docker Compose V2:

Docker Compose recently became production-ready with Compose specification V2 featuring:

  • Improved validation for deployments
  • Enhanced compatibility syntax with Kubernetes manifests
  • Support for environments and context concepts
  • Granular progress reporting during compose operations
  • Scaling indicators helping resource planning

Transition compose files via:

version: "2"

Leveraging these capabilities will streamline adoption at scale.

Troubleshooting Tips

Here are some best practices around resolving issues with docker CLI:

1. Inspect Docker Environment:

Validate if docker environment variables are correctly mapped:

env | grep DOCKER 

If configurations are missing, reconnect CLI to minikube Docker:

eval $(minikube docker-env)

2. Check Docker Engine Status:

Verify if Docker service is active within minikube:

minikube ssh 

sudo systemctl status docker  

# Restart if needed
sudo systemctl restart docker

exit

Then re-evaluate docker environment variables.

3. Monitor Minikube Logs:

If facing non-trivial issues, check minikube logs in debug mode:

minikube logs --loglevel debug -f

The above will print minikube internals helping identify problems like VM crashes or kubernetes failure.

4. Inspect Docker Logs:

Check docker daemon logs for errors:

journalctl -u docker.service -l --no-pager

# Errors or stack traces indicating failure 

5. Recreate Minikube:

As last resort, delete and recreate minikube:

minikube delete
rm -rf ~/.minikube 

minikube start

Follow the reconfiguration process to setup docker CLI again.

Adopting systematic troubleshooting approaches addresses most docker CLI issues.

Closing Thoughts

The Docker CLI continues to be the tool of choice for developers to script and automate container management at scale. This article showcased techniques to harness docker CLI effectively on Mac without needing the heavier Desktop runtime.

Minikube brings simplicity to quickly get started with CLI workflows for both Docker and Kubernetes locally. The portable skills translate seamlessly towards managed platforms later.

Combining native Mac tooling with minikube means you get the best of both worlds – a responsive CLI environment without compromises to access Docker natively on Mac.

So go ahead, explore Docker CLI capabilities further within minikube and shape the next generation of cloud-native apps!

Similar Posts