Class: MinimalPipeline::Docker

Inherits:
Object
  • Object
show all
Includes:
Rake::DSL
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.



24
25
# File 'lib/minimal_pipeline/docker.rb', line 24

def initialize
end

Instance Method Details

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

Builds a docker image from a Dockerfile

Parameters:

  • image_id (String)

    The name of the docker image

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

    The path to the Dockerfile

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

    Additional build args to pass to Docker

  • timeout (Integer) (defaults to: 600)

    The Docker build timeout



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/minimal_pipeline/docker.rb', line 77

def build_docker_image(image_id, dir = '.', 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,
    'buildargs' => JSON.dump(build_args)
  }
  puts "Build args: #{args.inspect}"
  ::Docker.options[:read_timeout] = timeout
  ::Docker::Image.build_from_dir(dir, args) { |v| build_output(v) }
end

#build_output(build_output) ⇒ Object

Outputs JSON build output lines as human readible text

Parameters:

  • build_output (String)

    Raw JSON build output line



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/minimal_pipeline/docker.rb', line 45

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



66
67
68
69
# File 'lib/minimal_pipeline/docker.rb', line 66

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

#ecr_loginObject

Logs in to AWS ECR



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

def 
  region = ENV['AWS_REGION'] || ENV['region']
  `$(aws ecr get-login --region #{region})`
end

#list_containersArray

List all containers in the ‘containers` directory

Returns:

  • (Array)

    List of container names



110
111
112
113
114
# File 'lib/minimal_pipeline/docker.rb', line 110

def list_containers
  containers = Dir.glob('containers/*')
  # Grab container name from containers/name/Dockerfile
  containers.map{ |container| container.split('/')[1] }
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



98
99
100
101
102
103
104
105
106
# File 'lib/minimal_pipeline/docker.rb', line 98

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



31
32
33
34
35
36
37
38
39
40
# File 'lib/minimal_pipeline/docker.rb', line 31

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