0
# Image Operations
1
2
This document covers comprehensive Docker image management including building, pulling, pushing, tagging, searching, and lifecycle operations.
3
4
## Image Listing and Inspection
5
6
### Listing Images
7
8
```java { .api }
9
import com.spotify.docker.client.DockerClient;
10
import com.spotify.docker.client.messages.Image;
11
12
// List all images
13
List<Image> images = docker.listImages();
14
15
// List all images including intermediates
16
List<Image> allImages = docker.listImages(
17
ListImagesParam.allImages()
18
);
19
20
// List dangling images (untagged)
21
List<Image> dangling = docker.listImages(
22
ListImagesParam.danglingImages()
23
);
24
25
// Filter by label
26
List<Image> labeled = docker.listImages(
27
ListImagesParam.withLabel("maintainer", "nginx")
28
);
29
30
// Filter by name pattern
31
List<Image> nginx = docker.listImages(
32
ListImagesParam.byName("nginx")
33
);
34
35
// Include digests in output
36
List<Image> withDigests = docker.listImages(
37
ListImagesParam.digests()
38
);
39
```
40
41
### Image Information
42
43
```java { .api }
44
// Get detailed image information
45
ImageInfo info = docker.inspectImage("nginx:latest");
46
47
System.out.println("Image ID: " + info.id());
48
System.out.println("Created: " + info.created());
49
System.out.println("Size: " + info.size());
50
System.out.println("Virtual Size: " + info.virtualSize());
51
System.out.println("Author: " + info.author());
52
System.out.println("Comment: " + info.comment());
53
System.out.println("Docker Version: " + info.dockerVersion());
54
System.out.println("Architecture: " + info.architecture());
55
System.out.println("OS: " + info.os());
56
57
// Repository tags and digests
58
List<String> tags = info.repoTags();
59
List<String> digests = info.repoDigests();
60
61
// Image configuration
62
ContainerConfig config = info.config();
63
System.out.println("Exposed Ports: " + config.exposedPorts());
64
System.out.println("Environment: " + config.env());
65
System.out.println("Entrypoint: " + config.entrypoint());
66
System.out.println("Cmd: " + config.cmd());
67
68
// Root filesystem info
69
RootFs rootFs = info.rootFs();
70
System.out.println("Root FS Type: " + rootFs.type());
71
System.out.println("Root FS Layers: " + rootFs.layers());
72
```
73
74
### Image History
75
76
```java { .api }
77
// Get image layer history
78
List<ImageHistory> history = docker.history("nginx:latest");
79
80
for (ImageHistory layer : history) {
81
System.out.println("Layer ID: " + layer.id());
82
System.out.println("Created: " + layer.created());
83
System.out.println("Created By: " + layer.createdBy());
84
System.out.println("Size: " + layer.size());
85
System.out.println("Tags: " + layer.tags());
86
System.out.println("Comment: " + layer.comment());
87
System.out.println("---");
88
}
89
```
90
91
## Image Building
92
93
### Basic Image Building
94
95
```java { .api }
96
import java.nio.file.Paths;
97
98
// Build from directory containing Dockerfile
99
String imageId = docker.build(Paths.get("/path/to/build/context"));
100
101
// Build with specific name and tag
102
String imageId = docker.build(
103
Paths.get("/path/to/build/context"),
104
"myapp:1.0"
105
);
106
107
// Build with custom Dockerfile path
108
String imageId = docker.build(
109
Paths.get("/path/to/build/context"),
110
"myapp:1.0",
111
BuildParam.dockerfile(Paths.get("custom.Dockerfile"))
112
);
113
```
114
115
### Advanced Build Parameters
116
117
```java { .api }
118
String imageId = docker.build(
119
Paths.get("/path/to/build/context"),
120
"myapp:latest",
121
BuildParam.name("myapp:1.0"), // Additional tag
122
BuildParam.quiet(), // Suppress verbose output
123
BuildParam.noCache(), // Don't use build cache
124
BuildParam.rm(), // Remove intermediate containers
125
BuildParam.forceRm(), // Always remove intermediate containers
126
BuildParam.pullNewerImage(), // Always pull newer base image
127
BuildParam.memory(1024L * 1024 * 1024), // Memory limit (1GB)
128
BuildParam.cpuShares(512), // CPU shares
129
BuildParam.dockerfile(Paths.get("Dockerfile.prod")) // Custom Dockerfile
130
);
131
```
132
133
### Build with Progress Handler
134
135
```java { .api }
136
import com.spotify.docker.client.ProgressHandler;
137
import com.spotify.docker.client.messages.ProgressMessage;
138
139
final AtomicReference<String> imageIdFromProgress = new AtomicReference<>();
140
141
String imageId = docker.build(
142
Paths.get("/path/to/dockerfile"),
143
"myapp:latest",
144
new ProgressHandler() {
145
@Override
146
public void progress(ProgressMessage message) throws DockerException {
147
String buildImageId = message.buildImageId();
148
if (buildImageId != null) {
149
imageIdFromProgress.set(buildImageId);
150
}
151
152
// Handle different message types
153
if (message.stream() != null) {
154
System.out.print(message.stream());
155
}
156
157
if (message.status() != null) {
158
System.out.println("Status: " + message.status());
159
}
160
161
if (message.error() != null) {
162
System.err.println("Error: " + message.error());
163
}
164
165
// Progress details
166
ProgressDetail detail = message.progressDetail();
167
if (detail != null) {
168
System.out.printf("Progress: %d/%d%n",
169
detail.current(), detail.total());
170
}
171
}
172
}
173
);
174
```
175
176
### Build from Git Repository
177
178
```java { .api }
179
// Build from remote Git repository
180
String imageId = docker.build(
181
Paths.get("."), // Not used for remote builds
182
"myapp:git",
183
BuildParam.remote(URI.create("https://github.com/user/repo.git#branch"))
184
);
185
186
// Build from Git with specific context
187
String imageId = docker.build(
188
Paths.get("."),
189
"myapp:git-subdir",
190
BuildParam.remote(URI.create("https://github.com/user/repo.git#:subdirectory"))
191
);
192
```
193
194
## Image Pulling and Pushing
195
196
### Pulling Images
197
198
```java { .api }
199
// Pull public image
200
docker.pull("nginx:latest");
201
202
// Pull specific tag
203
docker.pull("ubuntu:20.04");
204
205
// Pull with progress handler
206
docker.pull("large-image:latest", new ProgressHandler() {
207
@Override
208
public void progress(ProgressMessage message) throws DockerException {
209
if (message.status() != null) {
210
System.out.println("Pull status: " + message.status());
211
}
212
213
ProgressDetail detail = message.progressDetail();
214
if (detail != null && detail.total() != null && detail.total() > 0) {
215
double percentage = (double) detail.current() / detail.total() * 100;
216
System.out.printf("Progress: %.1f%%%n", percentage);
217
}
218
}
219
});
220
```
221
222
### Pulling Private Images
223
224
```java { .api }
225
import com.spotify.docker.client.messages.RegistryAuth;
226
227
// Create registry authentication
228
RegistryAuth auth = RegistryAuth.builder()
229
.username("myuser")
230
.password("mypassword")
231
.email("user@example.com")
232
.serverAddress("https://my-registry.com")
233
.build();
234
235
// Pull private image
236
docker.pull("my-registry.com/myapp:latest", auth);
237
238
// Pull private image with progress
239
docker.pull("my-registry.com/myapp:latest", auth, new ProgressHandler() {
240
@Override
241
public void progress(ProgressMessage message) throws DockerException {
242
System.out.println("Private pull: " + message.status());
243
}
244
});
245
```
246
247
### Pushing Images
248
249
```java { .api }
250
// Push public image
251
docker.push("myuser/myapp:latest");
252
253
// Push with progress handler
254
docker.push("myuser/myapp:latest", new ProgressHandler() {
255
@Override
256
public void progress(ProgressMessage message) throws DockerException {
257
if (message.status() != null) {
258
System.out.println("Push status: " + message.status());
259
}
260
}
261
});
262
263
// Push to private registry
264
RegistryAuth auth = RegistryAuth.builder()
265
.username("myuser")
266
.password("mypassword")
267
.serverAddress("https://my-registry.com")
268
.build();
269
270
docker.push("my-registry.com/myapp:latest", auth);
271
272
// Push to private registry with progress
273
docker.push("my-registry.com/myapp:latest", new ProgressHandler() {
274
@Override
275
public void progress(ProgressMessage message) throws DockerException {
276
System.out.println("Private push: " + message.status());
277
}
278
}, auth);
279
```
280
281
## Image Tagging
282
283
### Basic Tagging
284
285
```java { .api }
286
// Tag existing image
287
docker.tag("nginx:latest", "myapp/nginx:v1.0");
288
289
// Tag with force (overwrite existing tag)
290
docker.tag("nginx:latest", "myapp/nginx:latest", true);
291
292
// Tag for different registry
293
docker.tag("myapp:latest", "registry.example.com/myapp:1.0");
294
```
295
296
### Multi-Tag Strategy
297
298
```java { .api }
299
public void tagImageForRelease(DockerClient docker, String sourceImage, String version)
300
throws DockerException, InterruptedException {
301
302
String repository = "mycompany/myapp";
303
304
// Tag with specific version
305
docker.tag(sourceImage, repository + ":" + version);
306
307
// Tag as latest
308
docker.tag(sourceImage, repository + ":latest");
309
310
// Tag with major version
311
String majorVersion = version.split("\\.")[0];
312
docker.tag(sourceImage, repository + ":" + majorVersion);
313
314
// Tag for production registry
315
docker.tag(sourceImage, "prod-registry.com/" + repository + ":" + version);
316
}
317
```
318
319
## Image Creation and Loading
320
321
### Creating Images from Tarballs
322
323
```java { .api }
324
import java.io.*;
325
326
// Create image from tarball
327
File tarFile = new File("/path/to/image.tar");
328
try (InputStream imageInput = new BufferedInputStream(new FileInputStream(tarFile))) {
329
docker.create("myapp:from-tar", imageInput);
330
}
331
332
// Create with progress handler
333
try (InputStream imageInput = new BufferedInputStream(new FileInputStream(tarFile))) {
334
docker.create("myapp:from-tar", imageInput, new ProgressHandler() {
335
@Override
336
public void progress(ProgressMessage message) throws DockerException {
337
System.out.println("Create progress: " + message.status());
338
}
339
});
340
}
341
```
342
343
### Loading Images
344
345
```java { .api }
346
// Load single image from tarball
347
File imageFile = new File("/path/to/exported-image.tar");
348
try (InputStream imageInput = new BufferedInputStream(new FileInputStream(imageFile))) {
349
docker.load(imageInput);
350
}
351
352
// Load with progress tracking
353
try (InputStream imageInput = new BufferedInputStream(new FileInputStream(imageFile))) {
354
Set<String> loadedImages = docker.load(imageInput, new ProgressHandler() {
355
@Override
356
public void progress(ProgressMessage message) throws DockerException {
357
if (message.stream() != null) {
358
System.out.println("Load: " + message.stream());
359
}
360
}
361
});
362
363
System.out.println("Loaded images: " + loadedImages);
364
}
365
```
366
367
## Image Saving and Export
368
369
### Saving Single Image
370
371
```java { .api }
372
// Save image to tarball
373
try (InputStream imageData = docker.save("nginx:latest")) {
374
Files.copy(imageData, Paths.get("/path/to/nginx.tar"));
375
}
376
377
// Save with processing
378
try (InputStream imageData = docker.save("myapp:latest")) {
379
byte[] buffer = new byte[8192];
380
int bytesRead;
381
long totalBytes = 0;
382
383
try (FileOutputStream output = new FileOutputStream("/path/to/myapp.tar");
384
BufferedOutputStream buffered = new BufferedOutputStream(output)) {
385
386
while ((bytesRead = imageData.read(buffer)) != -1) {
387
buffered.write(buffer, 0, bytesRead);
388
totalBytes += bytesRead;
389
System.out.println("Saved: " + totalBytes + " bytes");
390
}
391
}
392
}
393
```
394
395
### Saving Multiple Images
396
397
```java { .api }
398
// Save multiple images to single tarball
399
try (InputStream multipleImages = docker.saveMultiple("nginx:latest", "redis:latest", "postgres:latest")) {
400
Files.copy(multipleImages, Paths.get("/path/to/multiple-images.tar"));
401
}
402
403
// Process multiple image tarball
404
try (InputStream imageData = docker.saveMultiple("app:v1", "app:v2", "app:latest");
405
TarArchiveInputStream tarStream = new TarArchiveInputStream(imageData)) {
406
407
TarArchiveEntry entry;
408
while ((entry = tarStream.getNextTarEntry()) != null) {
409
System.out.println("Archive entry: " + entry.getName());
410
if (entry.getName().equals("manifest.json")) {
411
// Process Docker manifest
412
byte[] manifest = new byte[(int) entry.getSize()];
413
tarStream.read(manifest);
414
System.out.println("Manifest: " + new String(manifest));
415
}
416
}
417
}
418
```
419
420
## Image Search
421
422
### Searching Docker Hub
423
424
```java { .api }
425
// Search for images
426
List<ImageSearchResult> results = docker.searchImages("nginx");
427
428
for (ImageSearchResult result : results) {
429
System.out.println("Name: " + result.name());
430
System.out.println("Description: " + result.description());
431
System.out.println("Stars: " + result.starCount());
432
System.out.println("Official: " + result.isOfficial());
433
System.out.println("Automated: " + result.isAutomated());
434
System.out.println("---");
435
}
436
437
// Search with filtering
438
List<ImageSearchResult> officialOnly = docker.searchImages("python")
439
.stream()
440
.filter(ImageSearchResult::isOfficial)
441
.collect(Collectors.toList());
442
```
443
444
## Image Removal
445
446
### Basic Image Removal
447
448
```java { .api }
449
// Remove single image
450
List<RemovedImage> removed = docker.removeImage("myapp:old");
451
452
for (RemovedImage removedImage : removed) {
453
if (removedImage.untagged() != null) {
454
System.out.println("Untagged: " + removedImage.untagged());
455
}
456
if (removedImage.deleted() != null) {
457
System.out.println("Deleted: " + removedImage.deleted());
458
}
459
}
460
461
// Force remove (remove even if containers are using it)
462
List<RemovedImage> forceRemoved = docker.removeImage("myapp:latest", true, false);
463
464
// Remove without pruning (don't delete untagged parent images)
465
List<RemovedImage> noPrune = docker.removeImage("myapp:latest", false, true);
466
```
467
468
### Bulk Image Cleanup
469
470
```java { .api }
471
public void cleanupUnusedImages(DockerClient docker)
472
throws DockerException, InterruptedException {
473
474
// Remove dangling images
475
List<Image> danglingImages = docker.listImages(ListImagesParam.danglingImages());
476
477
for (Image image : danglingImages) {
478
try {
479
List<RemovedImage> removed = docker.removeImage(image.id());
480
System.out.println("Removed dangling image: " + image.id());
481
} catch (DockerException e) {
482
System.err.println("Failed to remove " + image.id() + ": " + e.getMessage());
483
}
484
}
485
486
// Remove old images by pattern
487
List<Image> allImages = docker.listImages();
488
for (Image image : allImages) {
489
for (String tag : image.repoTags()) {
490
if (tag.matches("myapp:.*-SNAPSHOT")) {
491
try {
492
docker.removeImage(tag);
493
System.out.println("Removed snapshot image: " + tag);
494
} catch (DockerException e) {
495
System.err.println("Failed to remove " + tag + ": " + e.getMessage());
496
}
497
break;
498
}
499
}
500
}
501
}
502
```
503
504
## Image Commit
505
506
### Creating Images from Containers
507
508
```java { .api }
509
// Commit container to new image
510
ContainerCreation newImage = docker.commitContainer(
511
"container-id",
512
"myuser/myapp", // repository
513
"v1.0", // tag
514
containerConfig, // container configuration
515
"Initial commit", // commit message
516
"John Doe" // author
517
);
518
519
System.out.println("New image ID: " + newImage.id());
520
521
// Commit with minimal parameters
522
ContainerConfig config = ContainerConfig.builder()
523
.image("base-image")
524
.cmd("echo", "hello")
525
.build();
526
527
ContainerCreation committed = docker.commitContainer(
528
"container-id",
529
"myapp/committed",
530
"latest",
531
config,
532
null, // no message
533
null // no author
534
);
535
```
536
537
## Distribution Information
538
539
### Getting Distribution Metadata
540
541
```java { .api }
542
// Get distribution information (manifest, etc.)
543
Distribution distribution = docker.getDistribution("nginx:latest");
544
545
System.out.println("Descriptor:");
546
Descriptor descriptor = distribution.descriptor();
547
System.out.println(" Media Type: " + descriptor.mediaType());
548
System.out.println(" Size: " + descriptor.size());
549
System.out.println(" Digest: " + descriptor.digest());
550
551
// Platform information
552
for (Platform platform : distribution.platforms()) {
553
System.out.println("Platform:");
554
System.out.println(" Architecture: " + platform.architecture());
555
System.out.println(" OS: " + platform.os());
556
System.out.println(" Variant: " + platform.variant());
557
}
558
```
559
560
## Image Filtering Parameters
561
562
### ListImagesParam Options
563
564
```java { .api }
565
// Show all images including intermediates
566
ListImagesParam.allImages()
567
ListImagesParam.allImages(true)
568
569
// Show image digests
570
ListImagesParam.digests()
571
ListImagesParam.digests(true)
572
573
// Show dangling images only
574
ListImagesParam.danglingImages()
575
ListImagesParam.danglingImages(true)
576
577
// Filter by labels
578
ListImagesParam.withLabel("maintainer")
579
ListImagesParam.withLabel("version", "1.0")
580
581
// Filter by name/reference
582
ListImagesParam.byName("nginx")
583
ListImagesParam.byName("myregistry.com/myapp")
584
585
// Custom filters
586
ListImagesParam.filter("reference", "nginx:*")
587
ListImagesParam.filter("before", "image-id")
588
ListImagesParam.filter("since", "image-id")
589
ListImagesParam.filter("label", "key=value")
590
```
591
592
## Complete Image Pipeline Example
593
594
```java { .api }
595
public class ImagePipelineExample {
596
597
public void buildPushPipeline(DockerClient docker, String version)
598
throws DockerException, InterruptedException, IOException {
599
600
final String repository = "mycompany/myapp";
601
final Path buildContext = Paths.get("/app/source");
602
603
System.out.println("Starting build pipeline for version: " + version);
604
605
// 1. Build image with progress tracking
606
AtomicReference<String> builtImageId = new AtomicReference<>();
607
608
String imageId = docker.build(
609
buildContext,
610
repository + ":" + version,
611
BuildParam.rm(),
612
BuildParam.noCache(),
613
new ProgressHandler() {
614
@Override
615
public void progress(ProgressMessage message) throws DockerException {
616
if (message.buildImageId() != null) {
617
builtImageId.set(message.buildImageId());
618
}
619
if (message.stream() != null) {
620
System.out.print(message.stream());
621
}
622
}
623
}
624
);
625
626
System.out.println("Built image: " + imageId);
627
628
// 2. Tag for multiple targets
629
docker.tag(imageId, repository + ":latest");
630
docker.tag(imageId, repository + ":" + version);
631
632
String majorVersion = version.split("\\.")[0];
633
docker.tag(imageId, repository + ":" + majorVersion);
634
635
// 3. Push to registry with authentication
636
RegistryAuth auth = RegistryAuth.builder()
637
.username(System.getenv("DOCKER_USER"))
638
.password(System.getenv("DOCKER_PASSWORD"))
639
.build();
640
641
// Push all tags
642
String[] tags = {version, "latest", majorVersion};
643
for (String tag : tags) {
644
String fullTag = repository + ":" + tag;
645
System.out.println("Pushing " + fullTag);
646
647
docker.push(fullTag, new ProgressHandler() {
648
@Override
649
public void progress(ProgressMessage message) throws DockerException {
650
if (message.status() != null && message.id() != null) {
651
System.out.printf(" %s: %s%n", message.id(), message.status());
652
}
653
}
654
}, auth);
655
}
656
657
// 4. Verify image
658
ImageInfo info = docker.inspectImage(imageId);
659
System.out.println("Final image size: " + info.size() + " bytes");
660
System.out.println("Architecture: " + info.architecture());
661
662
// 5. Clean up old images
663
cleanupOldImages(docker, repository, version);
664
665
System.out.println("Pipeline completed successfully");
666
}
667
668
private void cleanupOldImages(DockerClient docker, String repository, String currentVersion)
669
throws DockerException, InterruptedException {
670
671
List<Image> images = docker.listImages();
672
for (Image image : images) {
673
for (String tag : image.repoTags()) {
674
if (tag.startsWith(repository + ":") &&
675
!tag.endsWith(":latest") &&
676
!tag.endsWith(":" + currentVersion)) {
677
678
try {
679
docker.removeImage(tag);
680
System.out.println("Removed old image: " + tag);
681
} catch (DockerException e) {
682
System.err.println("Could not remove " + tag + ": " + e.getMessage());
683
}
684
}
685
}
686
}
687
}
688
}
689
```
690
691
The image management system provides comprehensive control over Docker images with support for building, distribution, authentication, and lifecycle management suitable for CI/CD pipelines and production deployments.