Skip to content

Commit a6823bc

Browse files
committed
Fixed rootless linux
1 parent cf8d577 commit a6823bc

4 files changed

Lines changed: 243 additions & 126 deletions

File tree

build.gradle

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
plugins {
22
id "java"
3+
id "application"
34
id "com.github.johnrengelman.shadow" version "8.1.1"
45
id "io.github.intisy.github-gradle" version "1.4.4"
56
id "io.github.intisy.online-gradle" version "1.7.2"
@@ -25,9 +26,20 @@ java {
2526
}
2627

2728
dependencies {
28-
implementation "com.github.docker-java:docker-java:3.5.1"
29-
implementation 'com.github.docker-java:docker-java-transport-zerodep:3.5.1'
29+
implementation("com.github.docker-java:docker-java:3.5.1") {
30+
exclude group: 'com.github.docker-java', module: 'docker-java-transport-jersey'
31+
}
32+
implementation 'com.github.docker-java:docker-java-transport-httpclient5:3.5.1'
3033
implementation "com.google.code.gson:gson:2.10.1"
3134
implementation "org.apache.commons:commons-compress:1.24.0"
3235
implementation 'org.slf4j:slf4j-simple:2.0.7'
36+
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.1'
37+
}
38+
39+
application {
40+
mainClass = 'io.github.intisy.docker.EmbeddedDockerManager'
41+
}
42+
43+
test {
44+
useJUnitPlatform()
3345
}

src/main/java/io/github/intisy/docker/EmbeddedDockerManager.java

Lines changed: 70 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import com.github.dockerjava.api.model.ExposedPort;
66
import com.github.dockerjava.api.model.HostConfig;
77
import com.github.dockerjava.api.model.Ports;
8+
import com.github.dockerjava.api.exception.NotModifiedException;
9+
import com.github.dockerjava.api.command.InspectContainerResponse;
810

911
import java.util.concurrent.TimeUnit;
1012

@@ -13,64 +15,97 @@
1315
*/
1416
public class EmbeddedDockerManager {
1517

16-
private final DockerProvider provider;
18+
private final DockerProvider dockerProvider;
19+
private DockerClient dockerClient;
20+
private String containerId;
1721

1822
public EmbeddedDockerManager() {
19-
String osName = System.getProperty("os.name").toLowerCase();
20-
if (osName.contains("nix") || osName.contains("nux")) {
21-
this.provider = new LinuxDockerProvider();
22-
} else if (osName.contains("win")) {
23-
this.provider = new WindowsDockerProvider();
24-
} else if (osName.contains("mac")) {
25-
throw new UnsupportedOperationException("macOS is not yet supported.");
23+
String os = System.getProperty("os.name").toLowerCase();
24+
if (os.contains("linux")) {
25+
this.dockerProvider = new LinuxDockerProvider();
2626
} else {
27-
throw new UnsupportedOperationException("Unsupported Operating System: " + osName);
27+
throw new UnsupportedOperationException("Unsupported operating system: " + os);
2828
}
2929
}
3030

3131
public void initialize() throws Exception {
32-
provider.ensureInstalled();
33-
provider.start();
32+
dockerProvider.ensureInstalled();
33+
dockerProvider.start();
34+
this.dockerClient = dockerProvider.getClient();
3435
}
3536

36-
public void pullAndRunContainer(String imageName, int hostPort, int containerPort) throws InterruptedException {
37-
DockerClient client = provider.getClient();
38-
client.pullImageCmd(imageName)
39-
.withTag("latest")
40-
.exec(new PullImageResultCallback())
41-
.awaitCompletion(5, TimeUnit.MINUTES);
42-
43-
ExposedPort tcpContainerPort = ExposedPort.tcp(containerPort);
44-
Ports portBindings = new Ports();
45-
portBindings.bind(tcpContainerPort, Ports.Binding.bindPort(hostPort));
46-
47-
String containerId = client.createContainerCmd(imageName + ":latest")
48-
.withHostConfig(new HostConfig().withPortBindings(portBindings))
49-
.withExposedPorts(tcpContainerPort)
50-
.exec()
51-
.getId();
52-
53-
client.startContainerCmd(containerId).exec();
54-
System.out.printf("Started container %s. Port %d on host is mapped to %d in container.%n",
55-
containerId.substring(0, 12), hostPort, containerPort);
37+
public void pullAndRunContainer(String imageName, int containerPort) {
38+
try {
39+
String containerName = "docker-java-nginx-test";
40+
try {
41+
dockerClient.inspectContainerCmd(containerName).exec();
42+
System.out.println("Found existing container " + containerName + ". Removing it...");
43+
dockerClient.removeContainerCmd(containerName).withForce(true).exec();
44+
} catch (com.github.dockerjava.api.exception.NotFoundException ignored) {}
45+
46+
System.out.println("Pulling image: " + imageName);
47+
dockerClient.pullImageCmd(imageName)
48+
.exec(new PullImageResultCallback())
49+
.awaitCompletion(5, TimeUnit.MINUTES);
50+
51+
ExposedPort tcpContainerPort = ExposedPort.tcp(containerPort);
52+
Ports portBindings = new Ports();
53+
portBindings.bind(tcpContainerPort, Ports.Binding.empty());
54+
55+
this.containerId = dockerClient.createContainerCmd(imageName)
56+
.withName(containerName)
57+
.withHostConfig(new HostConfig().withPortBindings(portBindings))
58+
.withExposedPorts(tcpContainerPort)
59+
.exec()
60+
.getId();
61+
62+
dockerClient.startContainerCmd(this.containerId).exec();
63+
64+
InspectContainerResponse inspectResponse = dockerClient.inspectContainerCmd(this.containerId).exec();
65+
Ports.Binding[] bindings = inspectResponse.getNetworkSettings().getPorts().getBindings().get(tcpContainerPort);
66+
if (bindings == null || bindings.length == 0) {
67+
throw new RuntimeException("Port bindings not found for container " + this.containerId);
68+
}
69+
int assignedHostPort = Integer.parseInt(bindings[0].getHostPortSpec());
70+
71+
System.out.printf("Started container %s (%s). Port %d on host is mapped to %d in container.%n",
72+
containerName, this.containerId.substring(0, 12), assignedHostPort, containerPort);
73+
} catch (Exception e) {
74+
System.err.println("A critical error occurred:");
75+
throw new RuntimeException(e);
76+
}
77+
}
78+
79+
public void stopAndRemoveContainer() {
80+
if (containerId != null) {
81+
try {
82+
System.out.println("Attempting to stop and remove container " + containerId.substring(0, 12));
83+
dockerClient.stopContainerCmd(containerId).exec();
84+
dockerClient.removeContainerCmd(containerId).exec();
85+
System.out.println("Successfully removed container " + containerId.substring(0, 12));
86+
} catch (NotModifiedException e) {
87+
throw new RuntimeException(e);
88+
}
89+
}
5690
}
5791

5892
public void shutdown() {
59-
provider.stop();
93+
stopAndRemoveContainer();
94+
dockerProvider.stop();
6095
}
6196

6297
public static void main(String[] args) {
6398
EmbeddedDockerManager manager = new EmbeddedDockerManager();
6499
try {
65100
manager.initialize();
66-
manager.pullAndRunContainer("nginx:alpine", 8080, 80);
67-
System.out.println("Application is running. Press Ctrl+C to stop.");
101+
manager.pullAndRunContainer("nginx:alpine", 80);
102+
System.out.println("Container started successfully. The application will now shut down.");
68103
Runtime.getRuntime().addShutdownHook(new Thread(manager::shutdown));
69104

70105
} catch (Exception e) {
71106
System.err.println("A critical error occurred:");
72-
e.printStackTrace();
73107
manager.shutdown();
108+
throw new RuntimeException(e);
74109
}
75110
}
76111
}

0 commit comments

Comments
 (0)