Docker let you run applications or webapps under containers.

When working with automating deployment like Kubernetes, some bug or undesired behaviour can happen on a java application inside a container, but not reproducible outside the container.

Debug a container in IDE

It is quite easy to pass on debug mode when launching a container, by adding to the "docker run" command :

docker run -e \ (1)
"_JAVA_OPTIONS= -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=0.0.0.0:5005" \ (2)
-p 5005:5005 \ (3)
image-name:image-version (4)
1 Launches a container, using environment variable (`-e)
2 Permits remote java debugging, on port 5005 inside the created container, and waits for listener on this port before starting.
3 Binds port 5005 inside the container on port 5005 on the host.
4 Container will use the image image-name, and version image-version.

After executing the command, the container will be running, waiting for a listener on port 5005 to start. Take your favourite IDE and listen or attach process on port 5005, you’re on debug inside of your container.

Basic Example

Create a TestDebugMain.java in package "test", and put a breakpoint on the "System.out.println()" line :

package test;

public class TestDebugMain {

    public static void main(String[] args) {
        System.out.println("HelloWorld from Java Application running in Docker.");
    }
}

Create a folder "debug-test", put the TestDebugMain.java under "debug-test/test/". Create a Dockerfile under "debug-test" :

FROM java:8
COPY test/TestDebugMain.java /test/TestDebugMain.java
RUN javac test/TestDebugMain.java
CMD ["java", "test/TestDebugMain"]

Here is the final tree :

test-debug
├── Dockerfile
└── test
    └── TestDebugMain.java

With the terminal, go under "test-debug" folder, and build the docker image "test-debug", :

docker build -t test-debug .

finally, let’s launch a container with that image, and the debug mode, as explained at the begin of this topic (don’t forget to add the breakpoint in your IDE) :

docker run \
-e "_JAVA_OPTIONS= -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=0.0.0.0:5005" \
-p 5005:5005 test-debug:latest

Go to your IDE, and attach to process at port 5005, and that’s it !

From the same author:

In the same category: