1. 简介
最近有项目需要用java去操作docker,以前有过python-docker的经历,发现确实python更加好用一些,docker-java的api确有一些坑爹的地方。
2. 导入MAVEN依赖
搜maven repository 去maven网站,Maven Repository: Search/Browse/Explore (mvnrepository.com)https://mvnrepository.com/
然后搜索 docker-java,选一个你喜欢的版本
3. 连接到docker daemon
package com.xxx.dao.docker;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.core.DockerClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class BaseDockerClientProxy {
private DockerClient dockerClient;
@Value("${docker.host}")
private String serverUrl;
//等同于 : private String serverUrl="tcp://host:2375"
//因 此 : 你得保证你的host服务器的docker daemon是开放2375的
@Autowired
public void setDockerClient() {
// 这里就是获取dockerClient的方法了
dockerClient = DockerClientBuilder.getInstance(serverUrl).build();
}
public DockerClient getDockerClient() {
return dockerClient;
}
}
后续的所有操作,都是基于dockerClient进行的。
4. 创建一个容器
@Override
public String createContainer_() {
//给定一个容器的名字
name_ = "n4";
//这里是容器的初始化命令
List<String> cmds = new ArrayList<>();
cmds.add("/bin/bash");
cmds.add("-c");
cmds.add("python -m http.server 8092");
//cmd也可以通过数组传进去,下面的创建容器的方法中
//.withCmd()可以接受可变长度参数String...和List<String>两种
// 因此也可以定义cmds是下面这种形式:
// String[] cmds = new String[] { "/bin/bash/", "-c", "python -m http.server 8092" }
// 然后
// .withCmd(cmds)
// 当然也可以是下面这种格式:
// .withCmd("/bin/bash/", "-c", "python -m http.server 8092")
/**
类似的,几乎所有的.with方法都包含了一个List<T>参数或者可变长度的T...
.withPortBindings()有个小坑,我用python的时候,这个很简单,但是java却不是
当在该方法中指定了映射后,还要把端口暴漏出去,因此要和
.withExposedPorts()一起使用
即:
.withPortBindings(PortBinding.parse("8090:8092"), PortBinding.parse("8091:8093"))
.withExposedPorts(ExposedPort.tcp(8092), ExposedPort.tcp(8093))
*/
// 创建容器
CreateContainerResponse container = dockerClient.createContainerCmd("python")
.withName(name_)
.withCmd(cmds)
.withHostName("n4")
// 这里也可以接受List<String>参数
.withEnv("env1=env1", "env2=env2")
// 注意!这是绑定目录映射的,
// 目录映射不应该使用 .withVolumes()方法,这是在容器内部创建文件夹/卷的
.withBinds(Bind.parse("/data:/data"), Bind.parse("/tmp:/tmp"))
.withPortBindings(PortBinding.parse("8090:8092"), PortBinding.parse("8091:8093"))
.withExposedPorts(ExposedPort.tcp(8092), ExposedPort.tcp(8093))
.withWorkingDir("/root")
.exec();
dockerClient.startContainerCmd(container.getId()).exec();
return "succ";
}