Debugging Java Apps that run on Docker Containers

Ali Emrah Pekesen
KoçSistem

--

Introduction

Remote debugging capability is one of the daily needs of developers. In case we debug the application on our local machine with an IDE, it is easy to follow each line by breakpoints to see the problematical code block and fix it.

However, that is not the case in the real world most of the time. Most probably your apps run on containers and it means you should somehow attach to the java process to debug your app. Even though we have some options to find the problem, such as monitoring app insights (logs, dumps, etc), it is still difficult to understand the problem without debugging.

For such cases, we have a very strong feature on Java that is called remote debugging. JVM has been enhanced by a platform debugging architecture since 1.4 version, you may check JPDA documentation for further technical detail.

To be honest, I never recommend debugging on production because of its risks and drawbacks. You may write more unit tests or use an APM tool instead. Take a look here for more details.

In this article, we focus on understanding, “How to debug a java app runs on a docker container?”.

Before Start

Before we start exploring the remote debugging of containerized java apps, you should consider below bullets.

  • Enable JVM Debugging Mode
    JVM starts up with debugging disabled mode by default. You should enable debugging via passing some arguments (take a look here). If you do not, you would not be able to debug your java application remotely.
  • Do not keep your JVM running with debugging enabled
    Debug mode would affect performance and optimization. Also, keeping the remote debug socket open might be the cause of security vulnerabilities as well. That’s why you should disable JVM debugging mode back right after you complete the debugging process.

If you need to keep it as enabled for some reason, I strongly recommend you use a server-side proxy to prevent possible security problems in advance.

Let’s Start…

How to debug a java app runs on a docker container?

We are going to dockerize our java application with some java arguments to let the containerized java application be attachable. Let’s do it step by step together.

As we may suppose the run-up container is a remote server, we should change a bit our Dockerfile to initiate the java application as debugging enabled. Just create a Dockerfile as below;

FROM openjdk:8-jre-alpine
WORKDIR /app
ENV JAVA_TOOL_OPTIONS -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8090
COPY ./target/remoteDebugging-0.0.1-SNAPSHOT.jar /app/
ENTRYPOINT ["java", "-jar", "remoteDebugging-0.0.1-SNAPSHOT.jar"]
EXPOSE 8080
EXPOSE 8090

And build the docker image with the below command.

docker build -t remotedebuggingappsample:2.0 .

The container should run by exposing one more port to let the developers attach to the process in it.

docker run -d -p 8080:8080 -p 8090:8090 remotedebuggingappsample:2.0

Now we should configure our IDE for remote debugging with choosing the connection type and passing the host and port values. For this example, cause we ran up the container on our local docker daemon, the host is still “localhost”. However, you might be connecting to remote docker daemon, if so, put the remote host IP or DNS name instead of “localhost”.

Once you press the “Debug” button with the remote debugging configuration, you are going to be able to see the debugger works as expected. Let’s run the test from and see the result.

curl -X GET http://localhost:8080/Emrah

That’s all! You see how easy it is.

Conclusion

At the end of this article, you are able to debug your java application that runs on a docker container. I hope it helps and makes your daily routines easier. If you have any questions, do not hesitate to contact me.

--

--