A comprehensive Docker client library for Java applications providing programmatic Docker API access with container lifecycle management, image operations, and Docker Swarm support.
—
This document covers the complete container lifecycle management including creation, configuration, execution, monitoring, and file operations.
import com.spotify.docker.client.DockerClient;
import com.spotify.docker.client.messages.Container;
// List running containers (default)
List<Container> running = docker.listContainers();
// List all containers (including stopped)
List<Container> all = docker.listContainers(
ListContainersParam.allContainers()
);
// Filter by status
List<Container> exited = docker.listContainers(
ListContainersParam.withStatusExited()
);
// Filter by label
List<Container> labeled = docker.listContainers(
ListContainersParam.withLabel("env", "production")
);
// Combine parameters
List<Container> filtered = docker.listContainers(
ListContainersParam.allContainers(),
ListContainersParam.withLabel("app"),
ListContainersParam.limitContainers(10)
);import com.spotify.docker.client.messages.*;
// Simple container
ContainerConfig config = ContainerConfig.builder()
.image("nginx:latest")
.build();
ContainerCreation creation = docker.createContainer(config);
String containerId = creation.id();
// Named container
ContainerCreation creation = docker.createContainer(config, "my-web-server");ContainerConfig config = ContainerConfig.builder()
.image("nginx:latest")
.hostname("web-server")
.domainname("example.com")
.user("www-data")
.attachStdin(false)
.attachStdout(true)
.attachStderr(true)
.tty(true)
.openStdin(false)
.stdinOnce(false)
.env("NGINX_PORT=8080", "ENV=production")
.cmd("nginx", "-g", "daemon off;")
.entrypoint("/entrypoint.sh")
.exposedPorts("80/tcp", "443/tcp")
.volumes("/var/log/nginx", "/etc/nginx/conf.d")
.workingDir("/usr/share/nginx/html")
.labels(Map.of(
"app", "nginx",
"version", "1.0",
"env", "production"
))
.macAddress("02:42:ac:11:00:02")
.networkDisabled(false)
.stopSignal("SIGTERM")
.stopTimeout(30)
.build();
ContainerCreation creation = docker.createContainer(config);import com.spotify.docker.client.messages.*;
HostConfig hostConfig = HostConfig.builder()
// Resource limits
.memory(512L * 1024 * 1024) // 512MB
.memorySwap(1024L * 1024 * 1024) // 1GB total (512MB + 512MB swap)
.memoryReservation(256L * 1024 * 1024) // 256MB soft limit
.cpuShares(512) // CPU weight
.cpuQuota(50000L) // 50% of CPU
.cpuPeriod(100000L) // CPU period
.cpusetCpus("0-1") // Use cores 0 and 1
// Port bindings
.portBindings(Map.of(
"80/tcp", List.of(PortBinding.of("0.0.0.0", "8080")),
"443/tcp", List.of(PortBinding.of("0.0.0.0", "8443"))
))
.publishAllPorts(false)
// Volume mounts
.binds("/host/path:/container/path:ro",
"/logs:/var/log/nginx:rw")
.volumesFrom("data-container")
// Network configuration
.networkMode("bridge")
.links("database:db", "cache:redis")
.dns("8.8.8.8", "1.1.1.1")
.dnsSearch("example.com")
.extraHosts("host.docker.internal:host-gateway")
// Security
.privileged(false)
.readonlyRootfs(false)
.capAdd("NET_ADMIN")
.capDrop("MKNOD")
.securityOpt("no-new-privileges:true")
// Restart policy
.restartPolicy(RestartPolicy.builder()
.name("unless-stopped")
.maximumRetryCount(0)
.build())
// Devices
.devices(Device.builder()
.pathOnHost("/dev/sda")
.pathInContainer("/dev/xvda")
.cgroupPermissions("rwm")
.build())
// Resource constraints
.ulimits(Ulimit.builder()
.name("nofile")
.soft(1024L)
.hard(2048L)
.build())
.build();
ContainerConfig config = ContainerConfig.builder()
.image("nginx:latest")
.hostConfig(hostConfig)
.build();// Start container
docker.startContainer(containerId);
// Stop container (with timeout)
docker.stopContainer(containerId, 10); // Wait 10 seconds before SIGKILL
// Restart container
docker.restartContainer(containerId);
// Kill container
docker.killContainer(containerId);
// Kill with specific signal
docker.killContainer(containerId, DockerClient.Signal.SIGTERM);
// Pause container
docker.pauseContainer(containerId);
// Unpause container
docker.unpauseContainer(containerId);// Get detailed container information
ContainerInfo info = docker.inspectContainer(containerId);
System.out.println("Container ID: " + info.id());
System.out.println("Name: " + info.name());
System.out.println("Image: " + info.image());
System.out.println("State: " + info.state().running());
System.out.println("Exit Code: " + info.state().exitCode());
System.out.println("Started At: " + info.state().startedAt());
System.out.println("Finished At: " + info.state().finishedAt());
// Network settings
NetworkSettings network = info.networkSettings();
System.out.println("IP Address: " + network.ipAddress());
System.out.println("Gateway: " + network.gateway());
// Mounts
for (ContainerMount mount : info.mounts()) {
System.out.println("Mount: " + mount.source() + " -> " + mount.destination());
}// Get real-time container statistics
ContainerStats stats = docker.stats(containerId);
// CPU statistics
CpuStats cpuStats = stats.cpuStats();
System.out.println("CPU Usage: " + cpuStats.cpuUsage().totalUsage());
System.out.println("System CPU Usage: " + cpuStats.systemCpuUsage());
// Memory statistics
MemoryStats memStats = stats.memoryStats();
System.out.println("Memory Usage: " + memStats.usage());
System.out.println("Memory Limit: " + memStats.limit());
System.out.println("Max Usage: " + memStats.maxUsage());
// Network statistics
Map<String, NetworkStats> networks = stats.networks();
for (Map.Entry<String, NetworkStats> entry : networks.entrySet()) {
NetworkStats netStats = entry.getValue();
System.out.println("Network " + entry.getKey() + ":");
System.out.println(" RX Bytes: " + netStats.rxBytes());
System.out.println(" TX Bytes: " + netStats.txBytes());
}
// Block I/O statistics
BlockIoStats ioStats = stats.blockIoStats();
System.out.println("Block I/O Read: " + ioStats.ioServiceBytesRecursive());// List processes running in container
TopResults top = docker.topContainer(containerId);
System.out.println("Process Titles: " + top.titles());
for (List<String> process : top.processes()) {
System.out.println("Process: " + process);
}
// With custom ps arguments
TopResults topWithArgs = docker.topContainer(containerId, "aux");// Inspect filesystem changes
List<ContainerChange> changes = docker.inspectContainerChanges(containerId);
for (ContainerChange change : changes) {
System.out.println("Path: " + change.path());
System.out.println("Kind: " + change.kind()); // 0=Modified, 1=Added, 2=Deleted
}// Get all logs
try (LogStream logs = docker.logs(containerId,
LogsParam.stdout(),
LogsParam.stderr())) {
String logContent = logs.readFully();
System.out.println(logContent);
}
// Stream logs with parameters
try (LogStream logs = docker.logs(containerId,
LogsParam.follow(), // Follow log stream
LogsParam.stdout(true), // Include stdout
LogsParam.stderr(true), // Include stderr
LogsParam.since(1234567890), // Since timestamp
LogsParam.tail(100), // Last 100 lines
LogsParam.timestamps(true))) { // Include timestamps
String logLine;
while ((logLine = logs.readFully()) != null) {
System.out.println(logLine);
}
}try (LogStream logs = docker.logs(containerId,
LogsParam.stdout(), LogsParam.stderr(), LogsParam.follow())) {
logs.forEachRemaining(logMessage -> {
String content = logMessage.content().toStringUtf8();
LogMessage.Stream stream = logMessage.stream();
switch (stream) {
case STDOUT:
System.out.println("STDOUT: " + content);
break;
case STDERR:
System.err.println("STDERR: " + content);
break;
case STDIN:
System.out.println("STDIN: " + content);
break;
}
});
}// Create exec instance
ExecCreation exec = docker.execCreate(containerId,
new String[]{"bash", "-c", "echo 'Hello World'"},
ExecCreateParam.attachStdout(),
ExecCreateParam.attachStderr());
// Start execution and get output
try (LogStream execOutput = docker.execStart(exec.id())) {
String output = execOutput.readFully();
System.out.println("Output: " + output);
}
// Inspect exec state
ExecState execState = docker.execInspect(exec.id());
System.out.println("Exit Code: " + execState.exitCode());
System.out.println("Running: " + execState.running());// Interactive exec with TTY
ExecCreation exec = docker.execCreate(containerId,
new String[]{"bash"},
ExecCreateParam.attachStdin(),
ExecCreateParam.attachStdout(),
ExecCreateParam.attachStderr(),
ExecCreateParam.tty());
try (LogStream execStream = docker.execStart(exec.id(),
ExecStartParameter.TTY)) {
// Handle interactive session
// Note: Interactive sessions require special handling
// for stdin/stdout/stderr multiplexing
}ExecCreation exec = docker.execCreate(containerId,
new String[]{"whoami"},
ExecCreateParam.attachStdout(),
ExecCreateParam.user("nginx"),
ExecCreateParam.workingDir("/var/www"));
try (LogStream output = docker.execStart(exec.id())) {
System.out.println("User: " + output.readFully());
}import java.nio.file.*;
// Copy single file
Path sourceFile = Paths.get("/local/file.txt");
docker.copyToContainer(sourceFile, containerId, "/container/path/");
// Copy directory
Path sourceDir = Paths.get("/local/directory");
docker.copyToContainer(sourceDir, containerId, "/container/path/");
// Copy from InputStream
try (InputStream input = new FileInputStream("/local/file.txt")) {
docker.copyToContainer(input, containerId, "/container/path/file.txt");
}// Archive files from container
try (InputStream archive = docker.archiveContainer(containerId, "/path/in/container")) {
// Process tar archive
try (TarArchiveInputStream tarStream = new TarArchiveInputStream(archive)) {
TarArchiveEntry entry;
while ((entry = tarStream.getNextTarEntry()) != null) {
System.out.println("File: " + entry.getName());
System.out.println("Size: " + entry.getSize());
if (!entry.isDirectory()) {
// Read file content
byte[] content = new byte[(int) entry.getSize()];
tarStream.read(content);
// Process content
}
}
}
}// Attach to container
try (LogStream stream = docker.attachContainer(containerId,
AttachParameter.LOGS,
AttachParameter.STREAM,
AttachParameter.STDIN,
AttachParameter.STDOUT,
AttachParameter.STDERR)) {
// Read attached stream
stream.forEachRemaining(logMessage -> {
System.out.println(logMessage.content().toStringUtf8());
});
}// Resize container TTY
docker.resizeTty(containerId, 80, 24); // width=80, height=24
// Resize exec TTY
docker.execResizeTty(execId, 120, 30);// Wait for container to exit
ContainerExit exit = docker.waitContainer(containerId);
System.out.println("Exit status: " + exit.statusCode());// Rename container
docker.renameContainer(containerId, "new-container-name");// Update container resources
HostConfig newConfig = HostConfig.builder()
.memory(1024L * 1024 * 1024) // 1GB
.cpuShares(1024)
.build();
ContainerUpdate update = docker.updateContainer(containerId, newConfig);
System.out.println("Warnings: " + update.warnings());// Remove stopped container
docker.removeContainer(containerId);
// Force remove running container
docker.removeContainer(containerId,
RemoveContainerParam.forceKill());
// Remove container and its volumes
docker.removeContainer(containerId,
RemoveContainerParam.removeVolumes());
// Remove with multiple options
docker.removeContainer(containerId,
RemoveContainerParam.forceKill(),
RemoveContainerParam.removeVolumes());// Export container as tarball
try (InputStream export = docker.exportContainer(containerId)) {
// Save to file
Files.copy(export, Paths.get("/path/to/export.tar"));
}
// Process exported tarball
try (InputStream export = docker.exportContainer(containerId);
TarArchiveInputStream tarStream = new TarArchiveInputStream(export)) {
TarArchiveEntry entry;
while ((entry = tarStream.getNextTarEntry()) != null) {
System.out.println("Entry: " + entry.getName());
}
}// Status filters
ListContainersParam.withStatusCreated()
ListContainersParam.withStatusRestarting()
ListContainersParam.withStatusRunning()
ListContainersParam.withStatusPaused()
ListContainersParam.withStatusExited()
// Label filters
ListContainersParam.withLabel("key")
ListContainersParam.withLabel("key", "value")
// Other filters
ListContainersParam.allContainers(true)
ListContainersParam.limitContainers(10)
ListContainersParam.withContainerSizes(true)
ListContainersParam.containersCreatedSince("container-id")
ListContainersParam.containersCreatedBefore("container-id")
ListContainersParam.withExitStatus(0)
// Custom filters
ListContainersParam.filter("ancestor", "nginx")
ListContainersParam.filter("expose", "80")
ListContainersParam.filter("volume", "/data")public class ContainerLifecycleExample {
public void demonstrateLifecycle(DockerClient docker)
throws DockerException, InterruptedException {
// 1. Create container configuration
HostConfig hostConfig = HostConfig.builder()
.memory(512L * 1024 * 1024)
.portBindings(Map.of("80/tcp",
List.of(PortBinding.of("0.0.0.0", "8080"))))
.build();
ContainerConfig config = ContainerConfig.builder()
.image("nginx:latest")
.env("NGINX_PORT=80")
.exposedPorts("80/tcp")
.hostConfig(hostConfig)
.labels(Map.of("app", "demo", "env", "test"))
.build();
// 2. Create container
ContainerCreation creation = docker.createContainer(config, "demo-nginx");
String containerId = creation.id();
System.out.println("Created container: " + containerId);
try {
// 3. Start container
docker.startContainer(containerId);
System.out.println("Started container");
// 4. Wait for startup
Thread.sleep(2000);
// 5. Check container status
ContainerInfo info = docker.inspectContainer(containerId);
System.out.println("Container running: " + info.state().running());
// 6. Execute command
ExecCreation exec = docker.execCreate(containerId,
new String[]{"nginx", "-v"},
ExecCreateParam.attachStdout());
try (LogStream output = docker.execStart(exec.id())) {
System.out.println("Nginx version: " + output.readFully());
}
// 7. Get logs
try (LogStream logs = docker.logs(containerId,
LogsParam.stdout(), LogsParam.tail(10))) {
System.out.println("Container logs:\n" + logs.readFully());
}
// 8. Get statistics
ContainerStats stats = docker.stats(containerId);
System.out.println("Memory usage: " + stats.memoryStats().usage());
} finally {
// 9. Stop and remove container
try {
docker.stopContainer(containerId, 5);
System.out.println("Stopped container");
} catch (Exception e) {
System.err.println("Error stopping container: " + e.getMessage());
}
try {
docker.removeContainer(containerId);
System.out.println("Removed container");
} catch (Exception e) {
System.err.println("Error removing container: " + e.getMessage());
}
}
}
}This comprehensive container management system provides full lifecycle control with extensive configuration options, monitoring capabilities, and file operation support for production Docker deployments.
Install with Tessl CLI
npx tessl i tessl/maven-com-spotify--docker-client