0
# Volume Operations
1
2
This document covers Docker volume management including creation, inspection, mounting, and lifecycle operations for persistent data storage.
3
4
## Volume Listing and Inspection
5
6
### Listing Volumes
7
8
```java { .api }
9
import com.spotify.docker.client.DockerClient;
10
import com.spotify.docker.client.messages.Volume;
11
import com.spotify.docker.client.messages.VolumeList;
12
13
// List all volumes
14
VolumeList volumeList = docker.listVolumes();
15
List<Volume> volumes = volumeList.volumes();
16
List<String> warnings = volumeList.warnings();
17
18
// Display volume information
19
for (Volume volume : volumes) {
20
System.out.println("Volume: " + volume.name());
21
System.out.println("Driver: " + volume.driver());
22
System.out.println("Mountpoint: " + volume.mountpoint());
23
System.out.println("Scope: " + volume.scope());
24
}
25
26
// Check for warnings
27
if (!warnings.isEmpty()) {
28
System.out.println("Warnings: " + warnings);
29
}
30
```
31
32
### Volume Filtering
33
34
```java { .api }
35
// Filter volumes by name
36
VolumeList namedVolumes = docker.listVolumes(
37
ListVolumesParam.name("my-data-volume")
38
);
39
40
// Filter dangling volumes (not attached to any container)
41
VolumeList danglingVolumes = docker.listVolumes(
42
ListVolumesParam.dangling(true)
43
);
44
45
// Filter by driver
46
VolumeList localVolumes = docker.listVolumes(
47
ListVolumesParam.driver("local")
48
);
49
50
// Custom filters
51
VolumeList filtered = docker.listVolumes(
52
ListVolumesParam.filter("label", "environment=production")
53
);
54
```
55
56
### Volume Inspection
57
58
```java { .api }
59
// Inspect specific volume
60
Volume volume = docker.inspectVolume("volume-name-or-id");
61
62
System.out.println("Name: " + volume.name());
63
System.out.println("Driver: " + volume.driver());
64
System.out.println("Mountpoint: " + volume.mountpoint());
65
System.out.println("Scope: " + volume.scope());
66
67
// Volume labels
68
Map<String, String> labels = volume.labels();
69
if (labels != null) {
70
System.out.println("Labels:");
71
for (Map.Entry<String, String> entry : labels.entrySet()) {
72
System.out.println(" " + entry.getKey() + ": " + entry.getValue());
73
}
74
}
75
76
// Driver options
77
Map<String, String> options = volume.options();
78
if (options != null) {
79
System.out.println("Driver Options:");
80
for (Map.Entry<String, String> entry : options.entrySet()) {
81
System.out.println(" " + entry.getKey() + ": " + entry.getValue());
82
}
83
}
84
```
85
86
## Volume Creation
87
88
### Anonymous Volume Creation
89
90
```java { .api }
91
// Create anonymous volume (Docker generates name)
92
Volume anonymousVolume = docker.createVolume();
93
System.out.println("Created anonymous volume: " + anonymousVolume.name());
94
```
95
96
### Named Volume Creation
97
98
```java { .api }
99
import com.spotify.docker.client.messages.Volume;
100
101
// Create simple named volume
102
Volume simpleVolume = Volume.builder()
103
.name("my-data-volume")
104
.build();
105
106
Volume created = docker.createVolume(simpleVolume);
107
System.out.println("Created volume: " + created.name());
108
```
109
110
### Advanced Volume Configuration
111
112
```java { .api }
113
// Create volume with custom driver and options
114
Volume advancedVolume = Volume.builder()
115
.name("production-data")
116
.driver("local")
117
.labels(Map.of(
118
"environment", "production",
119
"application", "database",
120
"backup", "enabled"
121
))
122
.options(Map.of(
123
"type", "tmpfs",
124
"device", "tmpfs",
125
"o", "size=500m,uid=1000,gid=1000"
126
))
127
.build();
128
129
Volume created = docker.createVolume(advancedVolume);
130
```
131
132
### Driver-Specific Volume Creation
133
134
```java { .api }
135
// Local driver with bind mount
136
Volume bindVolume = Volume.builder()
137
.name("host-bind-volume")
138
.driver("local")
139
.options(Map.of(
140
"type", "bind",
141
"o", "bind",
142
"device", "/host/path/data"
143
))
144
.build();
145
146
// NFS volume
147
Volume nfsVolume = Volume.builder()
148
.name("nfs-shared-volume")
149
.driver("local")
150
.options(Map.of(
151
"type", "nfs",
152
"o", "addr=nfs.example.com,rw",
153
"device", ":/path/to/shared/data"
154
))
155
.build();
156
157
// tmpfs volume for temporary data
158
Volume tmpfsVolume = Volume.builder()
159
.name("temp-volume")
160
.driver("local")
161
.options(Map.of(
162
"type", "tmpfs",
163
"device", "tmpfs",
164
"o", "size=1g,mode=1777"
165
))
166
.build();
167
168
docker.createVolume(bindVolume);
169
docker.createVolume(nfsVolume);
170
docker.createVolume(tmpfsVolume);
171
```
172
173
## Volume Usage in Containers
174
175
### Container Volume Mounts
176
177
```java { .api }
178
// Using volumes in container configuration
179
ContainerConfig config = ContainerConfig.builder()
180
.image("postgres:13")
181
.env("POSTGRES_DB=myapp", "POSTGRES_PASSWORD=secret")
182
183
// Volume mount points (creates anonymous volumes)
184
.volumes("/var/lib/postgresql/data", "/var/log/postgresql")
185
186
.build();
187
188
// Host configuration with volume binds
189
HostConfig hostConfig = HostConfig.builder()
190
// Named volume mounts
191
.binds(
192
"postgres-data:/var/lib/postgresql/data",
193
"postgres-logs:/var/log/postgresql",
194
"/host/config:/etc/postgresql/conf.d:ro" // Read-only bind
195
)
196
197
// Alternative: using Mount objects for more control
198
.mounts(
199
Mount.builder()
200
.type("volume")
201
.source("postgres-data")
202
.target("/var/lib/postgresql/data")
203
.build(),
204
Mount.builder()
205
.type("bind")
206
.source("/host/backup")
207
.target("/backup")
208
.readOnly(true)
209
.build()
210
)
211
212
.build();
213
214
ContainerConfig fullConfig = config.toBuilder()
215
.hostConfig(hostConfig)
216
.build();
217
218
ContainerCreation container = docker.createContainer(fullConfig);
219
```
220
221
### Advanced Mount Configuration
222
223
```java { .api }
224
// Mount with detailed configuration
225
Mount dataMount = Mount.builder()
226
.type("volume")
227
.source("app-data")
228
.target("/app/data")
229
.readOnly(false)
230
231
// Volume options
232
.volumeOptions(VolumeOptions.builder()
233
.noCopy(false) // Copy data from container to volume on first mount
234
.labels(Map.of("mount-type", "data"))
235
.driverConfig(Driver.builder()
236
.name("local")
237
.options(Map.of("type", "ext4"))
238
.build())
239
.build())
240
241
// Bind options (for bind mounts)
242
.bindOptions(BindOptions.builder()
243
.propagation("rprivate")
244
.build())
245
246
// tmpfs options (for tmpfs mounts)
247
.tmpfsOptions(TmpfsOptions.builder()
248
.sizeBytes(1024L * 1024 * 1024) // 1GB
249
.mode(0755)
250
.build())
251
252
.build();
253
254
HostConfig hostConfig = HostConfig.builder()
255
.mounts(dataMount)
256
.build();
257
```
258
259
### Volume Binding Patterns
260
261
```java { .api }
262
public class VolumeBindingPatterns {
263
264
public void demonstrateBindPatterns(DockerClient docker)
265
throws DockerException, InterruptedException {
266
267
// 1. Named volume for persistent data
268
Volume dataVolume = Volume.builder()
269
.name("app-persistent-data")
270
.labels(Map.of("purpose", "application-data"))
271
.build();
272
docker.createVolume(dataVolume);
273
274
// 2. Bind mount for configuration
275
String configBind = "/host/app/config:/app/config:ro";
276
277
// 3. tmpfs for temporary/cache data
278
String tmpfsBind = "tmpfs:/tmp:tmpfs,size=500m";
279
280
// 4. Anonymous volume for logs
281
ContainerConfig config = ContainerConfig.builder()
282
.image("myapp:latest")
283
.volumes("/app/logs") // Anonymous volume
284
.hostConfig(HostConfig.builder()
285
.binds(
286
"app-persistent-data:/app/data", // Named volume
287
configBind, // Read-only bind
288
tmpfsBind // tmpfs mount
289
)
290
.build())
291
.build();
292
293
ContainerCreation container = docker.createContainer(config);
294
}
295
}
296
```
297
298
## Volume Removal
299
300
### Basic Volume Removal
301
302
```java { .api }
303
// Remove volume by name
304
docker.removeVolume("volume-name");
305
306
// Remove volume object
307
Volume volume = docker.inspectVolume("my-volume");
308
docker.removeVolume(volume);
309
```
310
311
### Safe Volume Removal
312
313
```java { .api }
314
public void safeVolumeRemoval(DockerClient docker, String volumeName) {
315
try {
316
// Check if volume exists
317
Volume volume = docker.inspectVolume(volumeName);
318
319
// Check if volume is in use by any containers
320
List<Container> containers = docker.listContainers(
321
DockerClient.ListContainersParam.allContainers()
322
);
323
324
boolean inUse = false;
325
for (Container container : containers) {
326
ContainerInfo info = docker.inspectContainer(container.id());
327
328
// Check mounts
329
for (ContainerMount mount : info.mounts()) {
330
if (volumeName.equals(mount.name()) ||
331
volumeName.equals(mount.source())) {
332
System.out.println("Volume in use by container: " + container.id());
333
inUse = true;
334
break;
335
}
336
}
337
}
338
339
if (!inUse) {
340
docker.removeVolume(volumeName);
341
System.out.println("Successfully removed volume: " + volumeName);
342
} else {
343
System.out.println("Volume is in use and cannot be removed");
344
}
345
346
} catch (DockerException | InterruptedException e) {
347
System.err.println("Error removing volume: " + e.getMessage());
348
}
349
}
350
```
351
352
### Bulk Volume Cleanup
353
354
```java { .api }
355
public void cleanupUnusedVolumes(DockerClient docker)
356
throws DockerException, InterruptedException {
357
358
// Get all dangling volumes
359
VolumeList danglingList = docker.listVolumes(
360
ListVolumesParam.dangling(true)
361
);
362
363
List<Volume> danglingVolumes = danglingList.volumes();
364
System.out.println("Found " + danglingVolumes.size() + " dangling volumes");
365
366
for (Volume volume : danglingVolumes) {
367
try {
368
docker.removeVolume(volume.name());
369
System.out.println("Removed dangling volume: " + volume.name());
370
} catch (DockerException e) {
371
System.err.println("Failed to remove volume " + volume.name() + ": " + e.getMessage());
372
}
373
}
374
375
// Remove volumes with specific labels (e.g., temporary volumes)
376
VolumeList allVolumes = docker.listVolumes();
377
for (Volume volume : allVolumes.volumes()) {
378
Map<String, String> labels = volume.labels();
379
if (labels != null && "true".equals(labels.get("temporary"))) {
380
try {
381
docker.removeVolume(volume.name());
382
System.out.println("Removed temporary volume: " + volume.name());
383
} catch (DockerException e) {
384
System.err.println("Failed to remove temporary volume " + volume.name() + ": " + e.getMessage());
385
}
386
}
387
}
388
}
389
```
390
391
## Volume Backup and Restore
392
393
### Volume Backup Strategy
394
395
```java { .api }
396
public void backupVolume(DockerClient docker, String volumeName, String backupPath)
397
throws DockerException, InterruptedException {
398
399
System.out.println("Starting backup of volume: " + volumeName);
400
401
// Create a temporary container to access the volume
402
ContainerConfig backupConfig = ContainerConfig.builder()
403
.image("alpine:latest")
404
.cmd("tar", "czf", "/backup/volume-backup.tar.gz", "-C", "/data", ".")
405
.volumes("/backup")
406
.hostConfig(HostConfig.builder()
407
.binds(
408
volumeName + ":/data:ro", // Mount volume as read-only
409
backupPath + ":/backup" // Mount backup destination
410
)
411
.autoRemove(AutoRemove.always()) // Auto-remove when done
412
.build())
413
.build();
414
415
ContainerCreation backupContainer = docker.createContainer(backupConfig);
416
417
try {
418
// Start backup process
419
docker.startContainer(backupContainer.id());
420
421
// Wait for completion
422
ContainerExit exit = docker.waitContainer(backupContainer.id());
423
424
if (exit.statusCode() == 0) {
425
System.out.println("Volume backup completed successfully");
426
} else {
427
System.err.println("Backup failed with exit code: " + exit.statusCode());
428
}
429
430
} finally {
431
// Container is auto-removed due to autoRemove setting
432
System.out.println("Backup container cleaned up");
433
}
434
}
435
```
436
437
### Volume Restore Strategy
438
439
```java { .api }
440
public void restoreVolume(DockerClient docker, String volumeName, String backupFile)
441
throws DockerException, InterruptedException {
442
443
System.out.println("Restoring volume: " + volumeName + " from " + backupFile);
444
445
// Ensure target volume exists
446
try {
447
docker.inspectVolume(volumeName);
448
} catch (Exception e) {
449
// Create volume if it doesn't exist
450
Volume newVolume = Volume.builder()
451
.name(volumeName)
452
.build();
453
docker.createVolume(newVolume);
454
System.out.println("Created new volume: " + volumeName);
455
}
456
457
// Create restore container
458
ContainerConfig restoreConfig = ContainerConfig.builder()
459
.image("alpine:latest")
460
.cmd("tar", "xzf", "/backup/" + new File(backupFile).getName(), "-C", "/data")
461
.volumes("/backup", "/data")
462
.hostConfig(HostConfig.builder()
463
.binds(
464
new File(backupFile).getParent() + ":/backup:ro",
465
volumeName + ":/data"
466
)
467
.autoRemove(AutoRemove.always())
468
.build())
469
.build();
470
471
ContainerCreation restoreContainer = docker.createContainer(restoreConfig);
472
473
try {
474
docker.startContainer(restoreContainer.id());
475
ContainerExit exit = docker.waitContainer(restoreContainer.id());
476
477
if (exit.statusCode() == 0) {
478
System.out.println("Volume restore completed successfully");
479
} else {
480
System.err.println("Restore failed with exit code: " + exit.statusCode());
481
}
482
483
} finally {
484
System.out.println("Restore container cleaned up");
485
}
486
}
487
```
488
489
## Volume Migration
490
491
### Volume Data Migration
492
493
```java { .api }
494
public void migrateVolumeData(DockerClient docker, String sourceVolume, String targetVolume)
495
throws DockerException, InterruptedException {
496
497
System.out.println("Migrating data from " + sourceVolume + " to " + targetVolume);
498
499
// Ensure target volume exists
500
Volume target = Volume.builder()
501
.name(targetVolume)
502
.build();
503
docker.createVolume(target);
504
505
// Create migration container
506
ContainerConfig migrationConfig = ContainerConfig.builder()
507
.image("alpine:latest")
508
.cmd("sh", "-c", "cp -av /source/. /target/")
509
.volumes("/source", "/target")
510
.hostConfig(HostConfig.builder()
511
.binds(
512
sourceVolume + ":/source:ro",
513
targetVolume + ":/target"
514
)
515
.autoRemove(AutoRemove.always())
516
.build())
517
.build();
518
519
ContainerCreation migrationContainer = docker.createContainer(migrationConfig);
520
521
try {
522
docker.startContainer(migrationContainer.id());
523
524
// Monitor progress with logs
525
try (LogStream logs = docker.logs(migrationContainer.id(),
526
DockerClient.LogsParam.follow(),
527
DockerClient.LogsParam.stdout(),
528
DockerClient.LogsParam.stderr())) {
529
530
logs.forEachRemaining(logMessage -> {
531
System.out.println("Migration: " + logMessage.content().toStringUtf8().trim());
532
});
533
}
534
535
ContainerExit exit = docker.waitContainer(migrationContainer.id());
536
537
if (exit.statusCode() == 0) {
538
System.out.println("Volume migration completed successfully");
539
540
// Verify migration
541
verifyVolumeMigration(docker, sourceVolume, targetVolume);
542
} else {
543
System.err.println("Migration failed with exit code: " + exit.statusCode());
544
}
545
546
} finally {
547
System.out.println("Migration container cleaned up");
548
}
549
}
550
551
private void verifyVolumeMigration(DockerClient docker, String sourceVolume, String targetVolume)
552
throws DockerException, InterruptedException {
553
554
// Create verification container
555
ContainerConfig verifyConfig = ContainerConfig.builder()
556
.image("alpine:latest")
557
.cmd("sh", "-c",
558
"echo 'Source files:' && find /source -type f | wc -l && " +
559
"echo 'Target files:' && find /target -type f | wc -l && " +
560
"echo 'Source size:' && du -sh /source && " +
561
"echo 'Target size:' && du -sh /target")
562
.hostConfig(HostConfig.builder()
563
.binds(
564
sourceVolume + ":/source:ro",
565
targetVolume + ":/target:ro"
566
)
567
.autoRemove(AutoRemove.always())
568
.build())
569
.build();
570
571
ContainerCreation verifyContainer = docker.createContainer(verifyConfig);
572
docker.startContainer(verifyContainer.id());
573
574
try (LogStream logs = docker.logs(verifyContainer.id(),
575
DockerClient.LogsParam.stdout(),
576
DockerClient.LogsParam.stderr())) {
577
578
String verification = logs.readFully();
579
System.out.println("Migration verification:\n" + verification);
580
}
581
582
docker.waitContainer(verifyContainer.id());
583
}
584
```
585
586
## Volume Monitoring and Management
587
588
### Volume Usage Analysis
589
590
```java { .api }
591
public void analyzeVolumeUsage(DockerClient docker)
592
throws DockerException, InterruptedException {
593
594
VolumeList volumeList = docker.listVolumes();
595
System.out.println("Volume Usage Analysis:");
596
System.out.println("Total volumes: " + volumeList.volumes().size());
597
598
Map<String, Integer> driverCount = new HashMap<>();
599
Map<String, List<Volume>> volumesByLabel = new HashMap<>();
600
601
for (Volume volume : volumeList.volumes()) {
602
// Count by driver
603
driverCount.merge(volume.driver(), 1, Integer::sum);
604
605
// Group by labels
606
Map<String, String> labels = volume.labels();
607
if (labels != null) {
608
for (String labelValue : labels.values()) {
609
volumesByLabel.computeIfAbsent(labelValue, k -> new ArrayList<>()).add(volume);
610
}
611
}
612
613
// Get size information (requires container to check)
614
getVolumeSize(docker, volume);
615
}
616
617
System.out.println("Volumes by driver:");
618
driverCount.forEach((driver, count) ->
619
System.out.println(" " + driver + ": " + count));
620
621
System.out.println("Volumes by label value:");
622
volumesByLabel.forEach((label, volumes) ->
623
System.out.println(" " + label + ": " + volumes.size() + " volumes"));
624
}
625
626
private void getVolumeSize(DockerClient docker, Volume volume) {
627
try {
628
ContainerConfig sizeCheckConfig = ContainerConfig.builder()
629
.image("alpine:latest")
630
.cmd("du", "-sh", "/data")
631
.hostConfig(HostConfig.builder()
632
.binds(volume.name() + ":/data:ro")
633
.autoRemove(AutoRemove.always())
634
.build())
635
.build();
636
637
ContainerCreation container = docker.createContainer(sizeCheckConfig);
638
docker.startContainer(container.id());
639
640
try (LogStream logs = docker.logs(container.id(),
641
DockerClient.LogsParam.stdout())) {
642
String sizeOutput = logs.readFully().trim();
643
System.out.println("Volume " + volume.name() + " size: " + sizeOutput);
644
}
645
646
docker.waitContainer(container.id());
647
648
} catch (Exception e) {
649
System.err.println("Could not get size for volume " + volume.name() + ": " + e.getMessage());
650
}
651
}
652
```
653
654
## Volume Filtering Parameters
655
656
### ListVolumesParam Options
657
658
```java { .api }
659
// Filter by volume name
660
ListVolumesParam.name("exact-volume-name")
661
662
// Filter dangling volumes
663
ListVolumesParam.dangling()
664
ListVolumesParam.dangling(true)
665
666
// Filter by driver
667
ListVolumesParam.driver("local")
668
ListVolumesParam.driver("nfs")
669
670
// Custom filters
671
ListVolumesParam.filter("scope", "local")
672
ListVolumesParam.filter("label", "environment=production")
673
ListVolumesParam.filter("label", "backup") // Has label key
674
```
675
676
## Complete Volume Management Example
677
678
```java { .api }
679
public class VolumeManagementExample {
680
681
public void demonstrateVolumeManagement(DockerClient docker)
682
throws DockerException, InterruptedException {
683
684
System.out.println("Starting comprehensive volume management demo...");
685
686
// 1. Create volumes for different purposes
687
createApplicationVolumes(docker);
688
689
// 2. Deploy application with volume mounts
690
deployApplicationWithVolumes(docker);
691
692
// 3. Perform volume operations
693
performVolumeOperations(docker);
694
695
// 4. Cleanup
696
cleanupVolumeDemo(docker);
697
}
698
699
private void createApplicationVolumes(DockerClient docker)
700
throws DockerException, InterruptedException {
701
702
System.out.println("Creating application volumes...");
703
704
// Database data volume
705
Volume dbData = Volume.builder()
706
.name("webapp-db-data")
707
.driver("local")
708
.labels(Map.of(
709
"application", "webapp",
710
"tier", "database",
711
"backup", "enabled"
712
))
713
.build();
714
715
// Application logs volume
716
Volume appLogs = Volume.builder()
717
.name("webapp-logs")
718
.driver("local")
719
.labels(Map.of(
720
"application", "webapp",
721
"tier", "application",
722
"retention", "30days"
723
))
724
.build();
725
726
// Cache volume (tmpfs)
727
Volume cacheVolume = Volume.builder()
728
.name("webapp-cache")
729
.driver("local")
730
.options(Map.of(
731
"type", "tmpfs",
732
"device", "tmpfs",
733
"o", "size=1g,mode=0755"
734
))
735
.labels(Map.of(
736
"application", "webapp",
737
"tier", "cache",
738
"temporary", "true"
739
))
740
.build();
741
742
docker.createVolume(dbData);
743
docker.createVolume(appLogs);
744
docker.createVolume(cacheVolume);
745
746
System.out.println("Created application volumes successfully");
747
}
748
749
private void deployApplicationWithVolumes(DockerClient docker)
750
throws DockerException, InterruptedException {
751
752
System.out.println("Deploying application with volume mounts...");
753
754
// Database container
755
ContainerConfig dbConfig = ContainerConfig.builder()
756
.image("postgres:13")
757
.env("POSTGRES_DB=webapp", "POSTGRES_USER=app", "POSTGRES_PASSWORD=secret")
758
.hostConfig(HostConfig.builder()
759
.binds("webapp-db-data:/var/lib/postgresql/data")
760
.build())
761
.build();
762
763
// Application container
764
ContainerConfig appConfig = ContainerConfig.builder()
765
.image("nginx:latest")
766
.hostConfig(HostConfig.builder()
767
.binds(
768
"webapp-logs:/var/log/nginx",
769
"webapp-cache:/var/cache/nginx"
770
)
771
.portBindings(Map.of("80/tcp",
772
List.of(PortBinding.of("0.0.0.0", "8080"))))
773
.build())
774
.build();
775
776
ContainerCreation dbContainer = docker.createContainer(dbConfig, "webapp-db");
777
ContainerCreation appContainer = docker.createContainer(appConfig, "webapp-app");
778
779
docker.startContainer(dbContainer.id());
780
docker.startContainer(appContainer.id());
781
782
System.out.println("Application deployed with volume mounts");
783
784
// Verify mounts
785
verifyContainerMounts(docker, appContainer.id());
786
}
787
788
private void verifyContainerMounts(DockerClient docker, String containerId)
789
throws DockerException, InterruptedException {
790
791
ContainerInfo info = docker.inspectContainer(containerId);
792
793
System.out.println("Container mounts for " + containerId + ":");
794
for (ContainerMount mount : info.mounts()) {
795
System.out.println(" Type: " + mount.type());
796
System.out.println(" Source: " + mount.source());
797
System.out.println(" Destination: " + mount.destination());
798
System.out.println(" Mode: " + mount.mode());
799
System.out.println(" RW: " + mount.rw());
800
System.out.println(" ---");
801
}
802
}
803
804
private void performVolumeOperations(DockerClient docker)
805
throws DockerException, InterruptedException {
806
807
System.out.println("Performing volume operations...");
808
809
// Backup database volume
810
backupVolume(docker, "webapp-db-data", "/tmp/backup");
811
812
// Analyze volume usage
813
analyzeVolumeUsage(docker);
814
815
// List volumes with specific labels
816
VolumeList webappVolumes = docker.listVolumes(
817
ListVolumesParam.filter("label", "application=webapp")
818
);
819
820
System.out.println("Webapp volumes:");
821
for (Volume volume : webappVolumes.volumes()) {
822
System.out.println(" " + volume.name() + " (" + volume.driver() + ")");
823
}
824
}
825
826
private void cleanupVolumeDemo(DockerClient docker) {
827
try {
828
System.out.println("Cleaning up volume demo...");
829
830
// Stop and remove containers
831
List<Container> containers = docker.listContainers(
832
DockerClient.ListContainersParam.allContainers()
833
);
834
835
for (Container container : containers) {
836
if (container.names().stream().anyMatch(name -> name.contains("webapp-"))) {
837
docker.stopContainer(container.id(), 5);
838
docker.removeContainer(container.id());
839
System.out.println("Removed container: " + container.id());
840
}
841
}
842
843
// Remove demo volumes
844
String[] volumesToRemove = {"webapp-db-data", "webapp-logs", "webapp-cache"};
845
for (String volumeName : volumesToRemove) {
846
try {
847
docker.removeVolume(volumeName);
848
System.out.println("Removed volume: " + volumeName);
849
} catch (Exception e) {
850
System.err.println("Could not remove volume " + volumeName + ": " + e.getMessage());
851
}
852
}
853
854
} catch (Exception e) {
855
System.err.println("Cleanup error: " + e.getMessage());
856
}
857
}
858
}
859
```
860
861
The volume management system provides comprehensive control over persistent storage with support for multiple storage drivers, backup strategies, data migration, and lifecycle management for containerized applications.