目标:让本地 Java 应用(运行在 Windows/macOS)通过 TCP 连接控制 Ubuntu 虚拟机中的 Docker 守护进程

🧩 背景说明

默认情况下,Docker 仅监听本地 Unix Socket(/var/run/docker.sock),无法被远程主机访问。

为了让 Java 程序通过 docker-java 库连接虚拟机中的 Docker,需启用 TCP 监听(如 2375 端口)

⚠️ 注意:Ubuntu 16.04+ 使用 systemd 管理服务,不能直接在 /etc/docker/daemon.json 中配置 hosts,否则会冲突!

🔧 配置步骤(使用 vi

  • 创建 systemd 覆盖目录

sudo mkdir -p /etc/systemd/system/docker.service.d
  • 用 vi 编辑 override 配置文件

sudo vi /etc/systemd/system/docker.service.d/override.conf
  • 输入以下内容:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
  • 重载配置并重启 Docker

sudo systemctl daemon-reload
sudo systemctl restart docker
  • 验证是否生效

# 检查 2375 端口是否监听
sudo netstat -tuln | grep 2375

# 测试 Docker API(应返回 JSON)
curl http://localhost:2375/version

✅ 成功标志:

  • 输出包含 tcp6 :::2375 LISTEN

  • curl 返回类似:

{"Version":"18.09.7", "Os":"linux", ...}

🌐 Java 代码连接示例

maven引入依赖

 <!-- Source: https://mvnrepository.com/artifact/com.github.docker-java/docker-java -->
        <dependency>
            <groupId>com.github.docker-java</groupId>
            <artifactId>docker-java</artifactId>
            <version>3.5.3</version>
            <scope>compile</scope>
        </dependency>
        <!-- Source: https://mvnrepository.com/artifact/com.github.docker-java/docker-java-transport-httpclient5 -->
        <dependency>
            <groupId>com.github.docker-java</groupId>
            <artifactId>docker-java-transport-httpclient5</artifactId>
            <version>3.5.3</version>
            <scope>compile</scope>
        </dependency>

Java 代码:

package com.okcl.codesanbox.docker;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.PingCmd;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;

public class DockerDemo {
    public static void main(String[] args) {
        String dockerHost = "tcp://192.168.58.100:2375"; // 你的 Ubuntu 虚拟机 IP

        // 1. 配置 Docker 客户端连接参数
        DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
                .withDockerHost(dockerHost)
                .build();

        // 2. 创建 HTTP 客户端(必须!)
        ApacheDockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
                .dockerHost(config.getDockerHost())
                .build();

        // 3. 构建 DockerClient

        try (DockerClient dockerClient = DockerClientBuilder.getInstance(config)
                .withDockerHttpClient(httpClient)
                .build()) {
            // 4. 测试连接
            PingCmd pingCmd = dockerClient.pingCmd();
            pingCmd.exec(); // 如果无异常,说明连接成功
            System.out.println("✅ 成功连接到远程 Docker Daemon!");
        } catch (Exception e) {
            System.err.println("❌ 连接失败: " + e.getMessage());
        }
    }
}

⚠️ 安全提醒

  • 端口无加密、无认证,任何能访问该端口的人都可完全控制 Docker(包括挂载宿主机、提权等)。

  • ✅ 仅限内网可信环境使用(如 VMware NAT/桥接网络)

  • ❌ 禁止暴露到公网

如需更高安全性,建议使用 SSH 隧道TLS 加密

📌 总结

步骤

关键点

配置方式

使用 systemd override,而非 daemon.json

监听地址

tcp://0.0.0.0:2375

Java 连接地址

tcp://<虚拟机IP>:2375

适用系统

Ubuntu 16.04+(systemd 环境)

💡 提示:此配置常用于远程开发、CI/CD 测试、IDE(如 IntelliJ + Remote Docker)等场景。