1. 概述

本文将介绍一个成熟的平台特定 API —— **Java Docker API 客户端**。我们将探讨如何连接运行中的 Docker 守护进程,以及该 API 为 Java 开发者提供的核心功能。

2. Maven 依赖

首先需要在 pom.xml 中添加核心依赖:

<dependency>
    <groupId>com.github.docker-java</groupId>
    <artifactId>docker-java</artifactId>
    <version>3.0.14</version>
</dependency>

提示:当前最新版本为 3.0.14,可通过 GitHub 发布页Maven 仓库 查看更新。

3. 使用 Docker 客户端

DockerClient 是连接 Docker 引擎/守护进程的核心类。默认情况下,Docker 守护进程仅通过 unix:///var/run/docker.sock 文件通信。

3.1 基础连接

使用默认配置创建连接:

DockerClient dockerClient = DockerClientBuilder.getInstance().build();

分步创建连接:

DefaultDockerClientConfig.Builder config 
  = DefaultDockerClientConfig.createDefaultConfigBuilder();
DockerClient dockerClient = DockerClientBuilder
  .getInstance(config)
  .build();

3.2 自定义连接配置

当 Docker 引擎监听 TCP 端口时(如 2375):

DockerClient dockerClient
  = DockerClientBuilder.getInstance("tcp://docker.baeldung.com:2375").build();

⚠️ 注意:连接字符串必须以 unix://tcp:// 开头

3.3 高级配置示例

使用 DefaultDockerClientConfig 进行完整配置:

DefaultDockerClientConfig config
  = DefaultDockerClientConfig.createDefaultConfigBuilder()
    .withRegistryEmail("[email protected]")
    .withRegistryPassword("baeldung")
    .withRegistryUsername("baeldung")
    .withDockerCertPath("/home/baeldung/.docker/certs")
    .withDockerConfig("/home/baeldung/.docker/")
    .withDockerTlsVerify("1")
    .withDockerHost("tcp://docker.baeldung.com:2376").build();

DockerClient dockerClient = DockerClientBuilder.getInstance(config).build();

3.4 使用 Properties 配置

Properties properties = new Properties();
properties.setProperty("registry.email", "[email protected]");
properties.setProperty("registry.password", "baeldung");
properties.setProperty("registry.username", "baeldung");
properties.setProperty("DOCKER_CERT_PATH", "/home/baeldung/.docker/certs");
properties.setProperty("DOCKER_CONFIG", "/home/baeldung/.docker/");
properties.setProperty("DOCKER_TLS_VERIFY", "1");
properties.setProperty("DOCKER_HOST", "tcp://docker.baeldung.com:2376");

DefaultDockerClientConfig config
  = DefaultDockerClientConfig.createDefaultConfigBuilder()
    .withProperties(properties).build();

DockerClient dockerClient = DockerClientBuilder.getInstance(config).build();

3.5 环境变量配置

通过环境变量简化配置:

export DOCKER_CERT_PATH=/home/baeldung/.docker/certs
export DOCKER_CONFIG=/home/baeldung/.docker/
export DOCKER_TLS_VERIFY=1
export DOCKER_HOST=tcp://docker.baeldung.com:2376

4. 容器管理

4.1 列出容器

列出运行中的容器:

List<Container> containers = dockerClient.listContainersCmd().exec();

高级查询(如查看已停止容器):

List<Container> containers = dockerClient.listContainersCmd()
  .withShowSize(true)
  .withShowAll(true)
  .withStatusFilter("exited").exec();

等价命令:

$ docker ps -a -s -f status=exited
# 或 
$ docker container ls -a -s -f status=exited

4.2 创建容器

假设有如下 Docker 命令:

$ docker create --name mongo \
  --hostname=baeldung \
  -e MONGO_LATEST_VERSION=3.6 \
  -p 9999:27017 \
  -v /Users/baeldung/mongo/data/db:/data/db \
  mongo:3.6 --bind_ip_all

Java 实现:

CreateContainerResponse container
  = dockerClient.createContainerCmd("mongo:3.6")
    .withCmd("--bind_ip_all")
    .withName("mongo")
    .withHostName("baeldung")
    .withEnv("MONGO_LATEST_VERSION=3.6")
    .withPortBindings(PortBinding.parse("9999:27017"))
    .withBinds(Bind.parse("/Users/baeldung/mongo/data/db:/data/db")).exec();

4.3 启动/停止/杀死容器

dockerClient.startContainerCmd(container.getId()).exec();
dockerClient.stopContainerCmd(container.getId()).exec();
dockerClient.killContainerCmd(container.getId()).exec();

4.4 检查容器

InspectContainerResponse container 
  = dockerClient.inspectContainerCmd(container.getId()).exec();

4.5 创建容器快照

类似 docker commit,从容器创建新镜像:

String snapshotId = dockerClient.commitCmd("3464bb547f88")
  .withAuthor("Baeldung <[email protected]>")
  .withEnv("SNAPSHOT_YEAR=2018")
  .withMessage("add git support")
  .withCmd("git", "version")
  .withRepository("alpine")
  .withTag("3.6.git").exec();

验证结果:

$ docker image ls alpine --format "table {{.Repository}} {{.Tag}}"
REPOSITORY TAG
alpine     3.6.git

5. 镜像管理

5.1 列出镜像

List<Image> images = dockerClient.listImagesCmd().exec();

包含中间层镜像:

List<Image> images = dockerClient.listImagesCmd()
  .withShowAll(true).exec();

仅显示悬空镜像:

List<Image> images = dockerClient.listImagesCmd()
  .withDanglingFilter(true).exec();

5.2 构建镜像

假设有如下 Dockerfile:

FROM alpine:3.6

RUN apk --update add git openssh && \
  rm -rf /var/lib/apt/lists/* && \
  rm /var/cache/apk/*

ENTRYPOINT ["git"]
CMD ["--help"]

Java 构建:

String imageId = dockerClient.buildImageCmd()
  .withDockerfile(new File("path/to/Dockerfile"))
  .withPull(true)
  .withNoCache(true)
  .withTag("alpine:git")
  .exec(new BuildImageResultCallback())
  .awaitImageId();

5.3 检查镜像

InspectImageResponse image 
  = dockerClient.inspectImageCmd("161714540c41").exec();

5.4 标记镜像

String imageId = "161714540c41";
String repository = "baeldung/alpine";
String tag = "git";

dockerClient.tagImageCmd(imageId, repository, tag).exec();

验证结果:

$ docker image ls --format "table {{.Repository}} {{.Tag}}"
REPOSITORY      TAG
baeldung/alpine git

5.5 推送镜像

⚠️ 注意:推送前需配置认证信息

dockerClient.pushImageCmd("baeldung/alpine")
  .withTag("git")
  .exec(new PushImageResultCallback())
  .awaitCompletion(90, TimeUnit.SECONDS);

5.6 拉取镜像

dockerClient.pullImageCmd("baeldung/alpine")
  .withTag("git")
  .exec(new PullImageResultCallback())
  .awaitCompletion(30, TimeUnit.SECONDS);

5.7 删除镜像

dockerClient.removeImageCmd("beaccc8687ae").exec();

5.8 搜索镜像

List<SearchItem> items = dockerClient.searchImagesCmd("Java").exec();

6. 卷管理

6.1 列出卷

ListVolumesResponse volumesResponse = dockerClient.listVolumesCmd().exec();
List<InspectVolumeResponse> volumes = volumesResponse.getVolumes();

6.2 检查卷

InspectVolumeResponse volume 
  = dockerClient.inspectVolumeCmd("0220b87330af5").exec();

6.3 创建卷

创建匿名卷:

CreateVolumeResponse unnamedVolume = dockerClient.createVolumeCmd().exec();

创建命名卷:

CreateVolumeResponse namedVolume 
  = dockerClient.createVolumeCmd().withName("myNamedVolume").exec();

6.4 删除卷

⚠️ 注意:正在使用的卷无法删除

dockerClient.removeVolumeCmd("myNamedVolume").exec();

7. 网络管理

7.1 列出网络

List<Network> networks = dockerClient.listNetworksCmd().exec();

7.2 创建网络

基础桥接网络:

CreateNetworkResponse networkResponse 
  = dockerClient.createNetworkCmd()
    .withName("baeldung")
    .withDriver("bridge").exec();

自定义子网:

CreateNetworkResponse networkResponse = dockerClient.createNetworkCmd()
  .withName("baeldung")
  .withIpam(new Ipam()
    .withConfig(new Config()
    .withSubnet("172.36.0.0/16")
    .withIpRange("172.36.5.0/24")))
  .withDriver("bridge").exec();

等价命令:

$ docker network create \
  --subnet=172.36.0.0/16 \
  --ip-range=172.36.5.0/24 \
  baeldung

7.3 检查网络

Network network 
  = dockerClient.inspectNetworkCmd().withNetworkId("baeldung").exec();

7.4 删除网络

dockerClient.removeNetworkCmd("baeldung").exec();

8. 总结

本文全面介绍了 Java Docker API 客户端 的核心功能,包括容器/镜像/卷/网络的管理操作,提供了多种实现方案。所有示例代码可在 GitHub 获取。


原始标题:A Docker Guide for Java | Baeldung