Class: Docker::API::Image

Inherits:
Resource show all
Defined in:
lib/docker/api/resources/image.rb

Overview

An image on the daemon.

Instance Attribute Summary

Attributes inherited from Resource

#client, #raw

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Resource

#==, #[], #hash, #id, #initialize, #partial?, #stale?, #to_s

Constructor Details

This class inherits a constructor from Docker::API::Resource

Class Method Details

.join_reference(repo, tag) ⇒ String

Put a repository and a tag or digest back together.

The inverse of split_reference, and it has to know which of the two it was handed: a tag joins with ":" and a digest joins with "@". A tag can never contain a colon, so the colon is the tell.

Examples:

join_reference("alpine", "3.20")         #=> "alpine:3.20"
join_reference("alpine", "sha256:1a2b")  #=> "alpine@sha256:1a2b"

Parameters:

  • repo (String)
  • tag (String, nil)

Returns:

  • (String)


167
168
169
170
171
# File 'lib/docker/api/resources/image.rb', line 167

def self.join_reference(repo, tag)
  return repo.to_s if tag.to_s.empty?

  tag.to_s.include?(":") ? "#{repo}@#{tag}" : "#{repo}:#{tag}"
end

.registry_for(repo) ⇒ String?

Returns the registry hostname, or nil for Docker Hub.

Parameters:

  • repo (String)

    a repository, possibly registry-qualified

Returns:

  • (String, nil)

    the registry hostname, or nil for Docker Hub



198
199
200
201
202
203
204
205
206
# File 'lib/docker/api/resources/image.rb', line 198

def self.registry_for(repo)
  first = repo.to_s.split("/").first
  return nil if first.nil?
  # A first segment is a registry only if it looks like a host: it has a
  # dot, a port, or is literally localhost. Otherwise it is a Hub org.
  return first if first.include?(".") || first.include?(":") || first == "localhost"

  nil
end

.split_reference(reference) ⇒ Array(String, String)

Split "registry.io/team/app:1.0" into its repository and tag.

Three colons can appear in a reference and only one of them separates a tag:

localhost:5000/app                  the colon is a registry port
alpine@sha256:1a2b...               the colon is inside a digest
registry.io/team/app:1.0            the colon is the tag separator

The digest form has to be taken off first, because "@" binds looser than the colon inside "sha256:..." and a right-hand partition on ":" would otherwise split the digest itself -- turning "alpine@sha256:1a2b" into the repository "alpine@sha256", which cannot exist. The daemon wants the digest whole, as the tag: ?fromImage=alpine&tag=sha256:1a2b is exactly what docker pull alpine@sha256:1a2b sends.

Examples:

split_reference("alpine")              #=> ["alpine", "latest"]
split_reference("localhost:5000/app")  #=> ["localhost:5000/app", "latest"]
split_reference("alpine@sha256:1a2b")  #=> ["alpine", "sha256:1a2b"]

Parameters:

  • reference (String)

Returns:

  • (Array(String, String))

    the repository and the tag or digest



143
144
145
146
147
148
149
150
151
152
# File 'lib/docker/api/resources/image.rb', line 143

def self.split_reference(reference)
  value = reference.to_s
  repo, separator, digest = value.rpartition("@")
  return [repo, digest] unless separator.empty?

  repo, _, tag = value.rpartition(":")
  return [value, "latest"] if repo.empty? || tag.include?("/")

  [repo, tag]
end

Instance Method Details

#digestsArray<String>

Returns the image's repository digests.

Returns:

  • (Array<String>)

    the image's repository digests



16
17
18
# File 'lib/docker/api/resources/image.rb', line 16

def digests
  detail("RepoDigests") || []
end

#history(platform: nil) ⇒ Array<Hash>

Returns the image's layer history.

Parameters:

  • platform (String, Hash, nil) (defaults to: nil)

    which variant's history to read

Returns:

  • (Array<Hash>)

    the image's layer history



105
106
107
# File 'lib/docker/api/resources/image.rb', line 105

def history(platform: nil)
  operations.image_history(name: id, platform: Platform.oci(platform)).json
end

#labelsHash

Returns the image's labels.

Returns:

  • (Hash)

    the image's labels



32
33
34
# File 'lib/docker/api/resources/image.rb', line 32

def labels
  detail("Config.Labels", "Labels") || {}
end

#nameString?

Returns the first tag, which is what people usually mean when they say "the image name".

Returns:

  • (String, nil)

    the first tag, which is what people usually mean when they say "the image name"



22
23
24
# File 'lib/docker/api/resources/image.rb', line 22

def name
  tags.first
end

#platformString?

Returns the platform this image was built for.

Returns:

  • (String, nil)

    the platform this image was built for



37
38
39
40
41
42
43
44
# File 'lib/docker/api/resources/image.rb', line 37

def platform
  os = detail("Os")
  architecture = detail("Architecture")
  return nil if os.nil? || architecture.nil?

  variant = detail("Variant")
  [os, architecture, variant].compact.join("/")
end

#push(tag: nil, auth: nil, platform: nil) {|event| ... } ⇒ self

Push this image to its registry.

Pushes the reference this object stands for, not the whole repository. The daemon pushes every tag under a repository when it is given no tag at all, so leaving it out meant image.push on an image tagged both app:1.0 and app:latest pushed both -- an unwelcome surprise when only one of them was meant to be published. tag: overrides; to push a whole repository deliberately, ask the daemon for it directly with client.operations.image_push(name: repo, x_registry_auth: ...).

Parameters:

  • tag (String, nil) (defaults to: nil)

    which tag to push, defaulting to this image's own

  • auth (String, nil) (defaults to: nil)

    an X-Registry-Auth value; resolved from the local Docker configuration when omitted

  • platform (String, Hash, nil) (defaults to: nil)

    which variant to push

Yield Parameters:

  • event (Hash)

    progress events as they arrive

Returns:

  • (self)

Raises:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/docker/api/resources/image.rb', line 88

def push(tag: nil, auth: nil, platform: nil, &block)
  repo, own_tag = self.class.split_reference(pushable_reference)
  tag ||= own_tag
  credentials = auth || Auth.resolve(self.class.registry_for(repo)) || Auth.encode({})

  stream = block ? Stream::JSONLines.new(&block) : nil
  operations.image_push(
    name: repo, tag: tag, x_registry_auth: credentials,
    platform: Platform.oci(platform)
  ) do |chunk|
    stream << chunk if stream
  end
  self
end

#reloadself

Returns:

  • (self)


47
48
49
# File 'lib/docker/api/resources/image.rb', line 47

def reload
  replace_raw(operations.image_inspect(name: id).json)
end

#remove(force: false, noprune: false) ⇒ Array<Hash>

Returns what the daemon deleted or untagged.

Parameters:

  • force (Boolean) (defaults to: false)

    remove even if tagged or in use

  • noprune (Boolean) (defaults to: false)

    keep untagged parents

Returns:

  • (Array<Hash>)

    what the daemon deleted or untagged



67
68
69
# File 'lib/docker/api/resources/image.rb', line 67

def remove(force: false, noprune: false)
  operations.image_delete(name: id, force: force, noprune: noprune).json
end

#save {|chunk| ... } ⇒ String, self

Write the image out as a tar archive.

Yield Parameters:

  • chunk (String)

    tar bytes, when a block is given

Returns:

  • (String, self)


113
114
115
116
117
118
# File 'lib/docker/api/resources/image.rb', line 113

def save(&block)
  return operations.image_get(name: id).body unless block

  operations.image_get(name: id, &block)
  self
end

#sizeInteger?

Returns size on disk, in bytes.

Returns:

  • (Integer, nil)

    size on disk, in bytes



27
28
29
# File 'lib/docker/api/resources/image.rb', line 27

def size
  detail("Size")
end

#tag(reference) ⇒ self

Give this image another name.

Examples:

image.tag("registry.example.com/team/app:2026.08")

Parameters:

  • reference (String)

    a full "repo:tag", or just a repo

Returns:

  • (self)


58
59
60
61
62
# File 'lib/docker/api/resources/image.rb', line 58

def tag(reference)
  repo, tag = self.class.split_reference(reference)
  operations.image_tag(name: id, repo: repo, tag: tag)
  reload
end

#tagsArray<String>

Returns every repository:tag this image answers to.

Returns:

  • (Array<String>)

    every repository:tag this image answers to



11
12
13
# File 'lib/docker/api/resources/image.rb', line 11

def tags
  detail("RepoTags") || []
end