basecamp/kamal · error · Kamal::Cli::DependencyError

Docker is not installed locally

Error message

Docker is not installed locally

What it means

Before building images or logging into the registry locally (kamal build, kamal registry login), Kamal runs a combined check `docker ... && docker buildx version` on the machine invoking kamal. If that SSHKit command fails with 'command not found' in the message, the docker binary itself is missing from PATH, and Kamal raises Kamal::Cli::DependencyError ('Docker is not installed locally') — distinct from the buildx-plugin variant chosen when docker exists but the plugin check fails.

Source

Thrown at lib/kamal/cli/base.rb:319

      def with_env(env)
        current_env = ENV.to_h.dup
        ENV.update(env)
        yield
      ensure
        ENV.clear
        ENV.update(current_env)
      end

      def ensure_docker_installed
        run_locally do
          begin
            execute *KAMAL.builder.ensure_docker_installed
          rescue SSHKit::Command::Failed => e
            error = e.message =~ /command not found/ ?
              "Docker is not installed locally" :
              "Docker buildx plugin is not installed locally"

            raise DependencyError, error
          end
        end
      end
  end
end

View on GitHub (pinned to eee0083b38)

Solutions

  1. Install Docker on the machine running kamal (Docker Desktop on macOS/Windows, docker-ce on Linux), then verify with `docker version` (non-root PATH included).
  2. In CI, use an image with the docker CLI or install it in the job before `kamal build` (e.g. apt-get install docker.io or use a docker:dind setup with the CLI available).
  3. If docker is installed but not found, fix PATH so the kamal process can see it (login shell, mise/asdf shims, systemd service Environment).
  4. If you only need remote operations, skip local checks where supported (e.g. `kamal registry login --skip-local`) or run builds where docker exists.

Example fix

# before (CI step)
- gem install kamal
- kamal build push   # DependencyError: Docker is not installed locally
# after
- gem install kamal
- apt-get update && apt-get install -y docker.io   # or use an image with docker CLI
- kamal build push
Defensive patterns

Strategy: validation

Validate before calling

abort "docker CLI not available" if `which docker`.empty?
system("kamal build")

Type guard

def docker_available?
  system("docker version >/dev/null 2>&1")
end

Try / catch

begin
  Kamal::CLI::Build.new.invoke(:push)
rescue Kamal::Cli::DependencyError => e
  abort "install docker CLI on this machine first: #{e.message}"
end

Prevention

When it happens

Trigger: Running `kamal build` (also `kamal build push`, `kamal registry login` without --skip-local) on a machine where `docker` is not on PATH: no Docker Desktop, docker CLI not installed, or running inside CI/containers where the docker socket/CLI are absent. The ensure_docker_installed helper at lib/kamal/cli/base.rb:310 catches SSHKit::Command::Failed and inspects the message for /command not found/.

Common situations: Fresh workstation without Docker Desktop installed; CI image (ruby:3.x) lacking the docker CLI; docker installed via asdf/mise shim not active in the deploy job's PATH; deploying from a server that only has the kamal gem.

Related errors


AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21). Data as JSON: /api/errors/742d717347194c68. Report an issue: GitHub.