55import com .github .dockerjava .api .model .ExposedPort ;
66import com .github .dockerjava .api .model .HostConfig ;
77import com .github .dockerjava .api .model .Ports ;
8+ import com .github .dockerjava .api .exception .NotModifiedException ;
9+ import com .github .dockerjava .api .command .InspectContainerResponse ;
810
911import java .util .concurrent .TimeUnit ;
1012
1315 */
1416public 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