module DockerHelper
Various helper methods to control the Docker command-line client. Main entrance point is the docker
helper. Use ::proxy
for a self-contained controller object to call these methods on.
See ::docker_command
Constants
- VERSION
Attributes
Setter for the Docker command (see ::docker_command
).
Public Class Methods
Returns the Docker command or aborts if none could be found.
Override by setting the DOCKER_COMMAND
environment variable or by setting the docker_command
attribute on this module.
# File lib/docker_helper.rb 58 def docker_command 59 @docker_command ||= ENV.fetch('DOCKER_COMMAND') { 60 find_docker_command || abort('Docker command not found.') } 61 end
Returns a new instance of Proxy
with helper methods available both in abbreviated and unabbreviated form.
# File lib/docker_helper.rb 47 def proxy 48 Proxy.new.extend(self) 49 end
Public Instance Methods
Central helper method to execute Docker commands.
If the command (first argument) is a symbol or if the pipe
option is set, runs the command through docker_pipe
and returns the result as a string. Otherwise, runs the command through docker_system
and returns true
or false
, indicating whether the command exited successfully or not.
In the pipe case, calls docker_fail
when the fail_if_empty
option is set and the command returned no result.
In the system case, ignores errors when the ignore_errors
option is set. The block is passed on to docker_system
if given.
# File lib/docker_helper.rb 132 def docker(*args, &block) 133 options, pipe, fail_if_empty, ignore_errors = DockerHelper. 134 extract_options(args, :pipe, :fail_if_empty, :ignore_errors) 135 136 DockerHelper.build_args(args, options) 137 138 if pipe 139 docker_pipe(*args).tap { |res| 140 if fail_if_empty && !res 141 docker_fail(*args) 142 end 143 } 144 else 145 if ignore_errors 146 options[:err] = :close 147 block ||= lambda { |*| } 148 end 149 150 docker_system(*args, &block) 151 end 152 end
Builds the image image
from the Dockerfile and context at build_path
.
Command reference: docker build
# File lib/docker_helper.rb 193 def docker_build(build_path, image = nil) 194 image ||= docker_image_name 195 196 docker %W[build -t #{image} #{build_path}] # --force-rm 197 end
Stops and then removes container name
, including associated volumes.
Command reference: docker rm
# File lib/docker_helper.rb 325 def docker_clean(name = nil, _ = nil) 326 name ||= docker_container_name 327 328 docker_stop name 329 docker %W[rm -v -f #{name}], ignore_errors: true 330 end
Removes container name
(see docker_clean
) as well as image image
.
Command reference: docker rmi
# File lib/docker_helper.rb 339 def docker_clobber(name = nil, image = nil) 340 name ||= docker_container_name 341 image ||= docker_image_name 342 343 docker_clean name 344 docker %W[rmi #{image}], ignore_errors: true 345 end
Returns the host and port for container name
on port port
. Fails if container is not running or the specified port is not exposed.
Command reference: docker port
# File lib/docker_helper.rb 220 def docker_port(port, name = nil) 221 name ||= docker_container_name 222 223 docker :port, name, port 224 end
Argument host_with_port
must be of the form host:port
, as returned by docker_port
, or an array of host and port.
Returns true
if and when the TCP port is available on the host and, if path
is given, a HTTP request for path
is successful.
Returns false
if the port and the path haven’t become available after 30 attempts each. Sleeps for 0.1 seconds inbetween attempts.
# File lib/docker_helper.rb 246 def docker_ready(host_with_port, path = nil, attempts = 30, sleep = 0.1) 247 host, port = host_with_port.is_a?(Array) ? 248 host_with_port : host_with_port.split(':') 249 250 docker_socket_ready(host, port, attempts, sleep) && 251 (!path || docker_http_ready(host, port, path, attempts, sleep)) 252 end
Resets container name
by removing (see docker_clean
) and then starting (see docker_start
) it from image image
.
# File lib/docker_helper.rb 352 def docker_reset(name = nil, image = nil) 353 docker_clean(name) 354 docker_start(name, image) 355 end
Restarts container name
by stopping (see docker_stop
) and then starting it.
Command reference: docker start
# File lib/docker_helper.rb 311 def docker_restart(name = nil, _ = nil) 312 name ||= docker_container_name 313 314 docker_stop name 315 docker %W[start #{name}] 316 end
Starts container name
from image image
. This will fail if a container with that name is already running. Use docker_start!
in case you want to unconditionally start the container.
Runs the container detached and with all exposed ports published.
Command reference: docker run
# File lib/docker_helper.rb 265 def docker_start(name = nil, image = nil) 266 name ||= docker_container_name 267 image ||= docker_image_name 268 269 docker %W[run -d -P --name #{name} #{image}] 270 end
Unconditionally starts container name
from image image
.
If the container is already running, it’s restarted (see docker_restart
). Otherwise, it’s started (see docker_start
) and its name
and image
are yielded to the block if given.
# File lib/docker_helper.rb 281 def docker_start!(name = nil, image = nil) 282 name ||= docker_container_name 283 image ||= docker_image_name 284 285 docker_restart(name) || docker_start(name, image).tap { 286 yield name, image if block_given? 287 } 288 end
Stops container name
.
Command reference: docker stop
# File lib/docker_helper.rb 297 def docker_stop(name = nil, _ = nil) 298 name ||= docker_container_name 299 300 docker %W[stop #{name}], ignore_errors: true 301 end
Returns the HTTP URL for container name
on port port
(see docker_port
).
# File lib/docker_helper.rb 231 def docker_url(port, name = nil) 232 "http://#{docker_port(port, name)}" 233 end
Returns the version number of the Docker client.
Command reference: docker version
# File lib/docker_helper.rb 161 def docker_version 162 docker(:version).lines.first.split.last 163 end
Returns the path to volume volume
shared by container name
.
Command reference: docker inspect
# File lib/docker_helper.rb 206 def docker_volume(volume, name = nil) 207 name ||= docker_container_name 208 209 docker :inspect, %W[-f {{index\ .Volumes\ "#{volume}"}} #{name}] 210 end
Private Instance Methods
Placeholder for default container name; must be implemented by utilizing class.
# File lib/docker_helper.rb 361 def docker_container_name 362 raise ArgumentError, 'container name missing', caller(1) 363 end
Simply aborts; override for different behaviour.
# File lib/docker_helper.rb 384 def docker_fail(*args) 385 abort 386 end
Checks HTTP connection.
# File lib/docker_helper.rb 398 def docker_http_ready(host, port, path, attempts, sleep) 399 loop { 400 begin 401 break if Net::HTTP.get_response(host, path, port).is_a?(Net::HTTPSuccess) 402 rescue Errno::ECONNRESET, EOFError => err 403 return false unless docker_ready_sleep(sleep, attempts -= 1) 404 retry 405 end 406 407 return false unless docker_ready_sleep(sleep, attempts -= 1) 408 } 409 410 true 411 end
Placeholder for default image name; must be implemented by utilizing class.
# File lib/docker_helper.rb 367 def docker_image_name 368 raise ArgumentError, 'image name missing', caller(1) 369 end
Executes the command in a subprocess and returns its output as a string, or nil
if output is empty; override for different behaviour.
# File lib/docker_helper.rb 373 def docker_pipe(*args) 374 res = IO.popen(args, &:read).chomp 375 res unless res.empty? 376 end
Sleeps unless out of attempts.
# File lib/docker_helper.rb 414 def docker_ready_sleep(sleep, attempts) 415 sleep(sleep) unless attempts.zero? 416 end
Checks TCP connection.
# File lib/docker_helper.rb 389 def docker_socket_ready(host, port, attempts, sleep) 390 TCPSocket.new(host, port).close 391 true 392 rescue Errno::ECONNREFUSED 393 return false unless docker_ready_sleep(sleep, attempts -= 1) 394 retry 395 end
Executes the command in a subshell; override for different behaviour.
# File lib/docker_helper.rb 379 def docker_system(*args) 380 system(*args) 381 end
Internal
↑ topPublic Class Methods
Builds arguments array suitable for docker_system
and docker_pipe
.
Prefixes the command with sudo
unless the NOSUDO
environment variable is set.
Flattens all arguments, converts them to strings and appends the options hash.
# File lib/docker_helper.rb 105 def build_args(args, options) 106 args.unshift(docker_command) 107 args.unshift(:sudo) unless ENV['NOSUDO'] 108 109 args.flatten! 110 args.map!(&:to_s) << options 111 end
Extracts options hash from args
and applies default options.
Returns the options hash as well as the values for keys
, which will be removed from the options.
# File lib/docker_helper.rb 82 def extract_options(args, *keys) 83 options = args.last.is_a?(Hash) ? args.pop : {} 84 85 unless options.key?(:pipe) 86 options[:pipe] = args.first.is_a?(Symbol) 87 end 88 89 unless options.key?(:fail_if_empty) 90 options[:fail_if_empty] = options[:pipe] 91 end 92 93 [options, *keys.map(&options.method(:delete))] 94 end
Tries to find the Docker command for the host system. Usually, it’s just docker
, but on Debian-based systems it’s docker.io
.
# File lib/docker_helper.rb 67 def find_docker_command 68 commands = %w[docker docker.io] 69 70 require 'nuggets/file/which' 71 File.which_command(commands) 72 rescue LoadError 73 commands.first 74 end