FLAMEDockerBackend.DockerAPI (flame_docker_backend v0.1.0)

Copy Markdown View Source

Thin wrapper over Docker Engine API via Unix socket.

Transport only — sends JSON bodies as-is. FLAMEDockerBackend builds the container create payloads; this module just relays them to Docker.

Uses OTP :httpc with a dedicated profile (:flame_docker) to isolate it from other :httpc users in the same BEAM.

Setup

Call init/1 once before any other function — typically from FLAMEDockerBackend.init/1.

On WSL2, pass the socket path explicitly:

DockerAPI.init("/mnt/wsl/shared-docker/docker.sock")

On macOS, Docker socket is mounted in user directory:

Path.join(System.user_home(), ".docker/run/docker.sock")
|> DockerAPI.init()

Workflow

Full round-trip — requires Docker to be running and init/1 called first:

iex> alias FLAMEDockerBackend.DockerAPI
FLAMEDockerBackend.DockerAPI
iex> {:ok, _pid} = DockerAPI.init()
iex> {:ok, _version} = DockerAPI.version()
iex> {:ok, _events} = DockerAPI.pull_image(%{"fromImage" => "hello-world"})
iex> {:ok, id} = DockerAPI.create_container(%{"name" => "doctest-workflow", "Image" => "hello-world"})
iex> is_binary(id)
true
iex> DockerAPI.start_container(id)
:ok
iex> {:ok, info} = DockerAPI.inspect_container(id)
iex> info["Name"]
"/doctest-workflow"
iex> DockerAPI.stop_and_remove_container(id)
:ok

Summary

Functions

Builds an image via the docker build CLI. Only used in tests.

Creates a container named params["name"] using the given Docker API body.

Creates a user-defined bridge network. Treats name conflict as success. Only used in tests.

Runs docker exec against a container name or ID. Only used in tests.

Checks if an image exists locally.

Initializes the :httpc profile for Unix socket communication with Docker.

Returns the full Docker API JSON object for the given container ID.

Lists containers.

Pulls fromImage from a registry.

Removes a container. Treats 404 (not found) as success.

Removes a network. Treats 404 as success. Only used in tests.

Starts a container. Treats 304 (already running) as success.

Stops, then forcefully removes a container.

Returns the Docker API version string reported by the daemon.

Functions

build_image(tag, dockerfile, context_dir)

@spec build_image(String.t(), String.t(), String.t()) ::
  {:ok, String.t()} | {:error, any()}

Builds an image via the docker build CLI. Only used in tests.

The HTTP build API is stream-heavy, so the CLI is used.

create_container(params)

@spec create_container(map()) :: {:ok, String.t()} | {:error, any()}

Creates a container named params["name"] using the given Docker API body.

Returns {:ok, id} where id is the full container ID.

create_network(name)

@spec create_network(String.t()) :: :ok | {:error, any()}

Creates a user-defined bridge network. Treats name conflict as success. Only used in tests.

exec(container, args)

@spec exec(String.t(), [String.t()]) :: {:ok, String.t()} | {:error, any()}

Runs docker exec against a container name or ID. Only used in tests.

image_exists?(image)

@spec image_exists?(String.t()) :: boolean()

Checks if an image exists locally.

init(socket \\ nil)

@spec init(String.t() | nil) :: {:ok, pid()} | {:error, any()}

Initializes the :httpc profile for Unix socket communication with Docker.

Idempotent — safe to call when the profile is already running.

inspect_container(id)

@spec inspect_container(String.t()) :: {:ok, map()} | {:error, any()}

Returns the full Docker API JSON object for the given container ID.

list_containers(opts \\ [])

@spec list_containers(keyword()) :: {:ok, [map()]} | {:error, any()}

Lists containers.

Options:

  • :all — include stopped containers (default false)
  • :filters — Docker filters map, e.g. %{"name" => ["minimal-flame"]}

pull_image(params)

@spec pull_image(map()) :: {:ok, [map()]} | {:error, any()}

Pulls fromImage from a registry.

Accepts any POST /images/create query parameters as map keys; "tag" defaults to "latest". Returns the list of JSON progress-event maps streamed by Docker during the pull.

remove_container(id, opts \\ [])

@spec remove_container(
  String.t(),
  keyword()
) :: :ok | {:error, any()}

Removes a container. Treats 404 (not found) as success.

Options:

  • :force — kill and remove a running container (default false)
  • :volumes — also remove anonymous volumes attached to the container (default false)

remove_network(name)

@spec remove_network(String.t()) :: :ok | {:error, any()}

Removes a network. Treats 404 as success. Only used in tests.

start_container(id)

@spec start_container(String.t()) :: :ok | {:error, any()}

Starts a container. Treats 304 (already running) as success.

stop_and_remove_container(id, timeout \\ 10)

@spec stop_and_remove_container(String.t(), non_neg_integer()) ::
  :ok | {:error, any()}

Stops, then forcefully removes a container.

Idempotent — safe to call on already-stopped, already-removed, or missing containers. timeout is forwarded to stop_container/2.

stop_container(id, timeout \\ 10)

@spec stop_container(String.t(), non_neg_integer()) :: :ok | {:error, any()}

Stops a container.

Treats 304 (already stopped) and 404 (not found) as success, making this safe to call on already-stopped or missing containers. timeout is the number of seconds Docker waits before killing; defaults to 10.

version()

@spec version() :: {:ok, String.t()} | {:error, any()}

Returns the Docker API version string reported by the daemon.