DockerAvailability is a small Elixir library for checking whether Docker is installed and usable from the current host process.
It checks more than the presence of the docker command. A host may have the Docker CLI installed while the Docker daemon is stopped, unreachable, or inaccessible to the current user. DockerAvailability probes both the Docker client and the Docker server so callers can fail early with clear diagnostics.
When the package is published to Hex, add docker_availability to your list of dependencies in mix.exs:
def deps do
[
{:docker_availability, "~> 1.0.0"}
]
endDuring development, you can also depend on this repository directly:
def deps do
[
{:docker_availability, github: "zacky1972/docker_availability", branch: "main"}
]
endThen fetch dependencies:
mix deps.get| Need | Use | Result |
|---|---|---|
| A simple yes/no answer | DockerAvailability.available?/0 |
true or false |
| The resolved Docker CLI path | DockerAvailability.executable/0 |
{:ok, path} or {:error, :docker_not_found} |
| Diagnostics, version information, or structured error handling | DockerAvailability.check/0 |
{:ok, info} or {:error, reason} |
Use available?/0 when a boolean is enough, for example when deciding whether to skip Docker-dependent work.
Use executable/0 when you only need to know whether the Docker CLI is installed and where it is located. This function does not check whether the Docker daemon is running or reachable.
Use check/0 when the caller needs diagnostic details, Docker client and server version information, or structured error handling.
Use available?/0 when you only need a boolean answer:
if DockerAvailability.available?() do
IO.puts("Docker is available")
else
IO.puts("Docker is not available")
endUse executable/0 when you only need to know whether the docker executable exists in PATH:
DockerAvailability.executable()
#=> {:ok, "/usr/bin/docker"}
DockerAvailability.executable()
#=> {:error, :docker_not_found}Use check/0 when you need diagnostic details:
case DockerAvailability.check() do
{:ok, info} ->
IO.puts("Docker executable: #{info.executable}")
IO.puts("Docker client: #{info.client_version}")
IO.puts("Docker server: #{info.server_version}")
{:error, :docker_not_found} ->
IO.puts("The docker executable was not found in PATH")
{:error, {:docker_command_failed, status, output}} ->
IO.puts("Docker client command failed with status #{status}")
IO.puts(output)
{:error, {:docker_unavailable, status, output}} ->
IO.puts("Docker daemon is not available with status #{status}")
IO.puts(output)
endReturns the path to the docker executable.
It only checks the current process PATH by using System.find_executable/1. It does not check whether the Docker daemon is running.
Return values:
{:ok, "/usr/bin/docker"}
{:error, :docker_not_found}{:ok, path} means the executable was found. path is the resolved path returned by the current process environment.
{:error, :docker_not_found} means no docker executable was available in PATH.
Returns true when Docker is installed and usable by the current process. This is a convenience wrapper around check/0.
Return values:
true
falseIt returns false for all error cases, including a missing executable, a failed Docker client command, or an unreachable Docker daemon.
Use check/0 instead when the caller needs to know why Docker is not available.
This function is limited to resolving the docker executable from the current process PATH. It does not run Docker commands, query Docker client or server version information, or verify Docker daemon reachability.
When the executable is found, the returned path is the resolved path returned by System.find_executable/1 and is not modified by this library.
Performs the full availability check. It verifies that:
- the
dockerexecutable exists inPATH - the Docker client version can be queried
- the Docker server version can be queried
Probe order:
- Resolve the Docker executable by calling
DockerAvailability.executable/0. - Run the resolved executable with the argument list
["version", "--format", "{{.Client.Version}}"]. - Only if the client-version command succeeds, run the same resolved executable with the argument list
["version", "--format", "{{.Server.Version}}"].
In shell form, the version probes are equivalent to:
/path/to/docker version --format '{{.Client.Version}}'
/path/to/docker version --format '{{.Server.Version}}'Returns {:ok, info} when Docker is usable:
{:ok,
%{
executable: "/usr/bin/docker",
client_version: "24.0.0",
server_version: "24.0.0"
}}The info map contains:
| Field | Meaning |
|---|---|
:executable |
The resolved path to the Docker executable. |
:client_version |
The Docker client version reported by the executable. |
:server_version |
The Docker server version reported by the daemon. |
The :client_version value is the trimmed output of the client-version command when that command exits with status 0.
The :server_version value is the trimmed output of the server-version command when that command exits with status 0.
Both version fields are returned as opaque strings. This library does not parse, normalize, or validate Docker version syntax beyond trimming surrounding whitespace.
The version fields are intended to be strings returned by Docker version commands.
Returns one of the following errors:
{:error, :docker_not_found}
{:error, {:docker_command_failed, status, output}}
{:error, {:docker_unavailable, status, output}}| Error | Meaning |
|---|---|
:docker_not_found |
No docker executable could be found in PATH. |
{:docker_command_failed, status, output} |
The Docker executable was found, but a Docker command failed while retrieving client information. |
{:docker_unavailable, status, output} |
The Docker client exists, but the Docker server or daemon is stopped, unreachable, or inaccessible to the current user. |
If the client-version command fails, check/0 returns {:error, {:docker_command_failed, status, output}}.
If the server-version command fails, check/0 returns {:error, {:docker_unavailable, status, output}}.
status is the Docker command exit status. output is the trimmed combined standard output and standard error from the Docker command.
DockerAvailability is a probe only. It does not:
- install Docker
- start or stop the Docker daemon
- pull, build, run, or remove Docker images or containers
- modify Docker state
- require a specific Docker image
A common use case is to skip Docker-dependent work when Docker is not available:
case DockerAvailability.check() do
{:ok, _info} ->
run_docker_dependent_work()
{:error, reason} ->
{:skip, {:docker_unavailable, reason}}
endFor test suites, available?/0 can be used to guard integration tests:
setup_all do
unless DockerAvailability.available?() do
ExUnit.configure(exclude: [:docker])
end
:ok
endRun the test suite with:
mix testThe unit tests use a fake docker executable placed in a temporary PATH, so they do not require a real Docker daemon or any Docker image.
Fetch dependencies:
mix deps.getRun tests:
mix testRun the project checks:
mix checkmix check validates the project from a contributor-facing perspective. It runs dependency auditing, compilation with warnings treated as errors, formatting checks, static analysis, dependency-lock validation, spelling checks, and Dialyzer.
Run the maintainer pre-commit checks before opening a pull request:
mix precommitmix precommit runs the maintainer workflow, including formatting, static checks, and tests. Contributors should run this command before submitting changes when the full toolchain is available locally.
Generate documentation locally with:
mix docsThe README is the primary user-facing guide and is included in the generated documentation. Keep the README and module documentation in sync when changing public API behavior, examples, or error descriptions.
After the package is published, documentation should be available on HexDocs.
- Elixir
~> 1.17 - Docker CLI and daemon, when checking real Docker availability at runtime
Copyright (c) 2026 University of Kitakyushu
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.