Current section

Files

Jump to
excontainers lib docker containers.ex
Raw

lib/docker/containers.ex

defmodule Docker.Containers do
@moduledoc false
alias Docker.WaitStrategy
def create(container_config, name \\ nil) do
Docker.Api.create_container(container_config, name)
end
def run(container_config, name \\ nil) do
case Docker.Api.create_container(container_config, name) do
{:ok, container_id} ->
start_and_wait(container_id, container_config)
{:error, {:http_error, 404}} ->
Docker.Images.pull(container_config.image)
run(container_config)
{:error, reason} ->
{:error, reason}
end
end
def start(container_id) do
Docker.Api.start_container(container_id)
end
def stop(container_id, options \\ []) do
Docker.Api.stop_container(container_id, options)
end
def info(container_id), do: Docker.Api.inspect_container(container_id)
def mapped_port(container, container_port), do: mapped_port(container, container_port, 5)
def mapped_port(_container, _container_port, 0), do: {:error, :missing_port}
def mapped_port(container, container_port, retries) do
container_port =
container_port
|> set_protocol_to_tcp_if_not_specified
with {:ok, info} <- info(container) do
port =
info.mapped_ports
|> Map.get(container_port)
case port do
nil ->
# Port mappings are not configured immediately after the container is creating. If the
# mapping is missing, sleeping and retrying is usually sufficient.
:timer.sleep(10)
mapped_port(container, container_port, retries - 1)
port ->
{:ok, String.to_integer(port)}
end
end
end
defp set_protocol_to_tcp_if_not_specified(port) when is_binary(port), do: port
defp set_protocol_to_tcp_if_not_specified(port) when is_integer(port), do: "#{port}/tcp"
defp start_and_wait(container_id, container_config) do
:ok = Docker.Containers.start(container_id)
if container_config.wait_strategy do
:ok = WaitStrategy.wait_until_container_is_ready(container_config.wait_strategy, container_id)
end
{:ok, container_id}
end
end