Couldn't connect to Docker daemon on Mac OS X

MacosDockerDocker ComposeDaemon

Macos Problem Overview


I would like to run multi-container application using docker-compose on Mac OS X El Capitan (v10.11.2).

However, the command $ docker-compose up command complains that it can't connect to the Docker daemon.

> ERROR: Couldn't connect to Docker daemon - you might need to run docker-machine start default.

Only after executing $ eval "$(docker-machine env default)" I do have access to the docker-compose command.

Why is this and how can I overcome this extra step?

Macos Solutions


Solution 1 - Macos

Update for Docker versions that come with Docker.app

The Docker experience on macOS has improved since this answer was posted:

  • The only prerequisite is now for Docker.app to be running. Note that starting it on demand takes a while, because the underlying Linux VM must be started.

  • Any shell then has access to Docker functionality.

By default, Docker.app is launched at login time (you can change that via its preferences).
If you instead prefer starting and stopping Docker on demand from the command line, here are bash scripts that do that, docker-start and docker-stop; place them anywhere in your $PATH.

When docker-start launches Docker.app, it waits until Docker has finished starting up and is ready.


docker-start:

#!/usr/bin/env bash

case $1 in
  -h|--help)
    echo $'usage: docker-start\n\nStarts Docker (Docker.app) on macOS and waits until the Docker environment is initialized.'
    exit 0
    ;;
esac
(( $# )) && { echo "ARGUMENT ERROR: Unexpected argument(s) specified. Use -h for help." >&2; exit 2; }

[[ $(uname) == 'Darwin' ]] || { echo "This function only runs on macOS." >&2; exit 2; }
  
echo "-- Starting Docker.app, if necessary..."

open -g -a Docker.app || exit

# Wait for the server to start up, if applicable.  
i=0
while ! docker system info &>/dev/null; do
  (( i++ == 0 )) && printf %s '-- Waiting for Docker to finish starting up...' || printf '.'
  sleep 1
done
(( i )) && printf '\n'

echo "-- Docker is ready."

docker-stop:

#!/usr/bin/env bash

case $1 in
  -h|--help)
    echo $'usage: docker-stop\n\nStops Docker (Docker.app) on macOS.'    
    exit 0
    ;;
esac
(( $# )) && { echo "ARGUMENT ERROR: Unexpected argument(s) specified. Use -h for help." >&2; exit 2; }

[[ $(uname) == 'Darwin' ]] || { echo "This function only runs on macOS." >&2; exit 2; }

echo "-- Quitting Docker.app, if running..."

osascript - <<'EOF' || exit
tell application "Docker"
  if it is running then quit it
end tell
EOF

echo "-- Docker is stopped."
echo "Caveat: Restarting it too quickly can cause errors."

Original, obsolete answer:

Kevan Ahlquist's helpful answer shows what commands to add to your Bash profile (~/.bash_profile) to automatically initialize Docker on opening an interactive shell.

Note that you can always initialize Docker in a new shell tab/window by opening application /Applications/Docker/Docker Quickstart Terminal.app (e.g., via Spotlight).
From an existing shell, you can invoke it as open -a 'Docker Quickstart Terminal.app' (which also opens a new shell tab).
What this answer offers is a convenient way to start Docker in the current shell.

Adding the Bash shell functions below - docker-start and docker-stop - improves on Kevan's approach in the following respects:

  • You can run docker-start on demand, without the overhead of starting the VM on opening the shell (once the Docker VM is running, initialization is much faster, but still takes a noticeable amount of time).
    (Of course, you can still opt to invoke docker-start right from your profile.)

  • docker-stop allows stopping Docker and cleaning up the environment variables on demand.

  • The functions ensure that Docker's error messages are not suppressed, and they pass Docker error exit codes through.

  • Additional status information is provided.

  • You may pass a VM name as a parameter; default is default.

Example:

$ docker-start
-- Starting Docker VM 'default' (`docker-machine start default`; this will take a while)...
Starting "default"...
(default) Check network to re-create if needed...
(default) Waiting for an IP...
Machine "default" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.
-- Setting DOCKER_* environment variables (`eval "$(docker-machine env default)"`)...
DOCKER_CERT_PATH="/Users/jdoe/.docker/machine/machines/default"
DOCKER_HOST="tcp://192.168.99.100:2376"
DOCKER_MACHINE_NAME="default"
DOCKER_TLS_VERIFY="1"
-- Docker VM 'default' is running.


$ docker-stop
-- Stopping Docker VM 'default' (`docker-machine stop default`)...
Stopping "default"...
Machine "default" was stopped.
-- Unsetting DOCKER_* environment variables (DOCKER_CERT_PATH, DOCKER_HOST, DOCKER_MACHINE_NAME, DOCKER_TLS_VERIFY)...
-- Docker VM 'default' is stopped.

Shell functions for on-demand starting and stopping of Docker (place them in, e.g., ~/.bash_profile for global availability in your interactive shells).

Note: The functions work in bash, ksh, and zsh, but in ksh you have to rename them so as not to include a '-' in the function names.

function docker-start {
  typeset vm=${1:-default} sts
  case $vm in
    -h|--help)
      echo $'usage: docker-start [<vm>]\n\nEnsures that the specified/default Docker VM is started\nand the environment is initialized.'
      return 0
      ;;
  esac
  sts=$(docker-machine status "$vm") || return
  [[ $sts == 'Running' ]] && echo "(Docker VM '$vm' is already running.)" || { 
    echo "-- Starting Docker VM '$vm' (\`docker-machine start "$vm"\`; this will take a while)..."; 
    docker-machine start "$vm" || return
  }
  echo "-- Setting DOCKER_* environment variables (\`eval \"\$(docker-machine env "$vm")\"\`)..."
  # Note: If the machine hasn't fully finished starting up yet from a
  #       previously launched-but-not-waited-for-completion `docker-machine status`,
  #       the following may output error messages; alas, without signaling failure
  #       via the exit code. Simply rerun this function to retry.
  eval "$(docker-machine env "$vm")" || return
  export | grep -o 'DOCKER_.*'
  echo "-- Docker VM '$vm' is running."
}

function docker-stop {
  typeset vm=${1:-default} sts envVarNames fndx
  case $vm in
    -h|--help)
      echo $'usage: docker-stop [<vm>]\n\nEnsures that the specified/default Docker VM is stopped\nand the environment is cleaned up.'
      return 0
      ;;
  esac
  sts=$(docker-machine status "$vm") || return
  [[ $sts == 'Running' ]] && { 
    echo "-- Stopping Docker VM '$vm' (\`docker-machine stop "$vm"\`)...";
    docker-machine stop "$vm" || return
  } || echo "(Docker VM '$vm' is not running.)"
  [[ -n $BASH_VERSION ]] && fndx=3 || fndx=1 # Bash prefixes defs. wit 'declare -x '
  envVarNames=( $(export | awk -v fndx="$fndx" '$fndx ~ /^DOCKER_/ { sub(/=.*/,"", $fndx); print $fndx }') )
  if [[ -n $envVarNames ]]; then
    echo "-- Unsetting DOCKER_* environment variables ($(echo "${envVarNames[@]}" | sed 's/ /, /g'))..."
    unset "${envVarNames[@]}"
  else
    echo "(No DOCKER_* environment variables to unset.)"
  fi
  echo "-- Docker VM '$vm' is stopped."
}

Solution 2 - Macos

I have the following in my ~/.bash_profile so I don't have to run the env command every time:

docker-machine start default 2>/dev/null # Hide output if machine is already running
eval `docker-machine env default`

Solution 3 - Macos

In the Quickstart Terminal, I restarted the "default" machine solved my problem

docker-machine restart default
eval $(docker-machine env default)

Then I was able to start composing my container with docker-compose up -d --build

Solution 4 - Macos

I my case helped: stop + remove all docker containers (Docker version 1.13.0-rc4)

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

After this "docker-compose up" run without Error "ERROR: Couldn't connect to Docker daemon. You might need to start Docker for Mac."

Perhaps in some cases this Error-message is only caused by another errors, i.e. memory space problems.

Solution 5 - Macos

I've written a Homebrew tap, here: https://github.com/nejckorasa/mac-docker-go

It includes a script to start/restart Docker daemon.

Usage: dckr [options]

Options:
  -k  | --kill        Kill Docker daemon
  -s  | --start       Start Docker daemon
  -r  | --restart     Restart Docker daemon
  -ka | --killall     Kill all running Docker containers
  -h                  Display help

  Defaults to restart if no options are present

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionndequekerView Question on Stackoverflow
Solution 1 - Macosmklement0View Answer on Stackoverflow
Solution 2 - MacosKevan AhlquistView Answer on Stackoverflow
Solution 3 - MacosTRicks43View Answer on Stackoverflow
Solution 4 - MacosGerdView Answer on Stackoverflow
Solution 5 - MacosnejckorasaView Answer on Stackoverflow