     end
   end
 
-  defp config_check do
+  defp config_check(pkg, name) do
+    {dockerfile, tag} =
+      (pkg.config[:provider_config] || [])
+      |> Keyword.get(:docker, {@dockerfile, @tag})
+
+    dockerfile =
+      dockerfile
+      |> Path.relative_to_cwd
+      |> Path.expand
+
     # Check for the Cache Volume
     unless cache_volume?() do
       cache_volume_create()
     end
 
-    unless docker_image?() do
-      docker_image_create()
+    unless docker_image?(tag) do
+      docker_image_create(dockerfile, tag)
+    end
+
+    unless container?(name) do
+      container_create(pkg, name, tag)
     end
     :ok
   end
 
-  defp docker_image? do
-    cmd = "docker"
-    args = ["images", "-f", "label=#{@label}", "-q"]
+  defp container?(name) do
+    cmd = "docker"
+    args = ["ps", "-a", "-f", "name=#{name}", "-q"]
     case System.cmd(cmd, args, stderr_to_stdout: true) do
       {"", _} ->
         false

    else
      Mix.raise "Docker provider expected artifact to exist at #{tar_file}"
    end
  end

  def shell(_pkg) do

  end

  defp build_paths(pkg) do


  @label "org.nerves-project.nerves_system_br=1.0"
  @dockerfile File.cwd!
              |> Path.join("template/Dockerfile")
  @working_dir "/nerves/build"

  def artifact(pkg, toolchain, _opts) do
    container = preflight(pkg)
    artifact_name = Artifact.name(pkg, toolchain)

    {:ok, pid} = Nerves.Utils.Stream.start_link(file: "build.log")
    stream = IO.stream(pid, :line)

    container_ensure_started(container)

    :ok = create_build(pkg, container, stream)
    :ok = make(container, stream)
    :ok = make_artifact(artifact_name, container, stream)
    :ok = copy_artifact(pkg, toolchain, container, stream)

    container_stop(container)
  end

  # def shell(pkg, _opts) do
  #   _container = preflight(pkg)
  #   :ok
  # end
  #
  # def clean(_pkg, _opts) do
  #   :ok
  # end

  defp preflight(pkg) do
    checksum = Nerves.Package.checksum(pkg)

    id_file =
      Mix.Project.build_path
      |> Path.join("nerves/.docker_id")

    id =
      if File.exists?(id_file) do
        File.read!(id_file)
      else
        id = :crypto.strong_rand_bytes(16) |> Base.encode64 |> binary_part(0, 16)
        Path.dirname(id_file)
        |> File.mkdir_p!
        File.write!(id_file, id)
        id
      end

    name = "#{id}-#{pkg.app}-#{checksum}"

    _ = host_check()
    _ = config_check(pkg, name)

    name
  end

  defp create_build(pkg, container, stream) do
    platform_config = pkg.config[:platform_config][:defconfig]
    defconfig = Path.join("/nerves/env/#{pkg.app}", platform_config)

    Nerves.Utils.Shell.info "Starting Docker Build...(this may take a while)"
    args = [
      "exec",
      "-i",
      container,
      "/nerves/env/platform/create-build.sh",
      defconfig,
      @working_dir]

    case Mix.Nerves.Utils.shell("docker", args, stream: stream) do
      {_result, 0} ->
        :ok
      {_result, _} ->
        Mix.raise """
        Docker provider encountered an error.
        See build.log for more details.
        """
    end
  end

  defp make(container, stream) do

    args = [
      "exec",
      "-i",
      container,
      "make"]

    case Mix.Nerves.Utils.shell("docker", args, stream: stream) do
      {_result, 0} ->
        :ok
      {_result, _} ->
        Mix.raise """
        Docker provider encountered an error.
        See build.log for more details.
        """
    end
  end

  defp make_artifact(name, container, stream) do
    Nerves.Utils.Shell.info "Compressing artifact"
    args = [
      "exec",
      "-i",
      container,
      "make",
      "system",
      "NERVES_ARTIFACT_NAME=#{name}"]

    case Mix.Nerves.Utils.shell("docker", args, stream: stream) do
      {_result, 0} ->
        :ok
      {_result, _} ->
        Mix.raise """
        Docker provider encountered an error.
        See build.log for more details.
        """
    end
  end

  defp copy_artifact(pkg, toolchain, container, stream) do
    Nerves.Utils.Shell.info "Copying artifact to host"
    name = Artifact.name(pkg, toolchain)

    args = [
      "exec",
      "-i",
      container,
      "cp",
      "#{name}.tar.gz",
      "/nerves/host/artifacts/#{name}.tar.gz"]

    case Mix.Nerves.Utils.shell("docker", args, stream: stream) do
      {_result, 0} ->
        :ok
      {_result, _} ->
        Mix.raise """
        Docker provider encountered an error.
        See build.log for more details.
        """
    end

    base_dir = Artifact.base_dir(pkg)
    tar_file = Path.join(base_dir, "#{Artifact.name(pkg, toolchain)}.tar.gz")

    if File.exists?(tar_file) do
      dir = Artifact.dir(pkg, toolchain)
      File.mkdir_p(dir)
