Class: MinimalPipeline::Docker

Inherits:
Object
  • Object
show all
Defined in:
lib/minimal_pipeline/docker.rb

Overview

Here is an example of how to use this class to manage Docker containers.

“‘ docker = MinimalPipeline::Docker.new keystore = MinimalPipeline::Keystore.new

deploy_env = ENV docker_repo = keystore.retrieve(“#deploy_env_EXAMPLE_ECR_REPO”) docker_image = “#docker_repo/example:latest” docker.build_docker_image(docker_image, ‘containers/example’) docker.push_docker_image(docker_image) “‘

Instance Method Summary collapse

Constructor Details

#initializeDocker

Returns a new instance of Docker.



22
# File 'lib/minimal_pipeline/docker.rb', line 22

def initialize; end

Instance Method Details

#build_docker_image(image_id, build_context = '.', dockerfile = 'Dockerfile', build_args: {}, timeout: 600) ⇒ Object

Builds a docker image from a Dockerfile

Parameters:

  • image_id (String)

    The name of the docker image

  • build_context (String) (defaults to: '.')

    The build context for Dockerfile

  • dockerfile (String) (defaults to: 'Dockerfile')

    The path to Dockerfile

  • build_args (Hash) (defaults to: {})

    Additional build args to pass to Docker

  • timeout (Integer) (defaults to: 600)

    The Docker build timeout



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/minimal_pipeline/docker.rb', line 69

def build_docker_image(image_id, build_context = '.',
                       dockerfile = 'Dockerfile',
                       build_args: {},
                       timeout: 600)
  %w[HTTP_PROXY HTTPS_PROXY NO_PROXY http_proxy https_proxy
     no_proxy].each do |arg|
    build_args[arg] = ENV[arg] if ENV[arg]
  end

  args = {
    'nocache' => 'true',
    'pull' => 'true',
    't' => image_id,
    'dockerfile' => dockerfile,
    'buildargs' => JSON.dump(build_args)
  }
  puts "Build args: #{args.inspect}" if ENV['DEBUG']
  ::Docker.options[:read_timeout] = timeout
  ::Docker::Image.build_from_dir(build_context, args) do |value|
    build_output(value)
  end
end

#build_output(build_output) ⇒ Object

Outputs JSON build output lines as human readible text

Parameters:

  • build_output (String)

    Raw JSON build output line



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/minimal_pipeline/docker.rb', line 42

def build_output(build_output)
  # Each line of the response is its own JSON structure
  build_output.each_line do |l|
    if (log = JSON.parse(l)) && log.key?('stream')
      $stdout.puts log['stream']
    end
  end
rescue JSON::ParserError
  $stdout.puts "Bad JSON parse\n"
  $stdout.puts build_output
end

#clean_up_image(image_id) ⇒ Object

Cleans up docker images

Parameters:

  • image_id (String)

    The Docker container ID to delete



57
58
59
60
# File 'lib/minimal_pipeline/docker.rb', line 57

def clean_up_image(image_id)
  image = ::Docker::Image.get(image_id)
  image.remove(force: true)
end

#push_docker_image(image_id) ⇒ Object

Pushes a docker image from local to AWS ECR. This handles login, the upload, and local cleanup of the container

Parameters:

  • image_id (String)

    The name of the docker image



96
97
98
99
100
101
102
103
# File 'lib/minimal_pipeline/docker.rb', line 96

def push_docker_image(image_id)
  docker_bin = which('docker')
  raise "docker_push: no docker binary: #{image_id}" unless docker_bin
  stdout, stderr, status = Open3.capture3(docker_bin, 'push', image_id)
  raise "stdout: #{stdout}\nstderr: #{stderr}\nstatus: #{status}" \
    unless status.exitstatus.zero?
  clean_up_image(image_id)
end

#which(cmd) ⇒ String

Finds the absolute path to a given executable

Parameters:

  • cmd (String)

    The name of the executable to locate

Returns:

  • (String)

    The absolute path to the executable



28
29
30
31
32
33
34
35
36
37
# File 'lib/minimal_pipeline/docker.rb', line 28

def which(cmd)
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each do |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return exe if File.executable?(exe) && !File.directory?(exe)
    end
  end
  nil
end