Access tomcat running in docker container by JMX

I want to get tomcat's performance by JMX. Tomcat version is 7 and Java version is 1.7.0_79.

Tomcat runs on the docker's container. The port mapping has set up by the following.

docker run -itd -p 18080:8080 -p 19998:19998 -p 62911:62911 sad_jang2 bash

In the tomcat container, setevn.sh was created in the path, /tomcat_home/bin/ with the following content.

export JAVA_OPTS="
-Xdebug -Xrunjdwp:transport=dt_socket,address=62911,server=y,suspend=n
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=19998
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=172.17.0.16"

I write a simple java code as

JMXServiceURL serviceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + "172.17.0.16"+ ":" + "19998" + "/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(serviceURL, null);
MBeanServerConnection mbsc = connector.getMBeanServerConnection();

and can get related values by JMX.

However, I run this code in my desktop with the docker host's address and 19998 port such as

JMXServiceURL serviceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + "10.70.1.5"+ ":" + "19998" + "/jmxrmi");

The console displayed the following message

java.rmi.ConnectException: Connection refused to host: 172.17.0.16; nested exception is: 
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)
at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2432)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:308)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:270)
at utility.GetStatistic.getTomcatStats(GetStatistic.java:84)
at exec.Main.main(Main.java:53)

Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 9 more

Using the browser to connect the URL http://10.70.1.5:18080 can show the tomcat root's page.

Can anyone give any suggestions? Thanks.

Here's the flags I've successfully used for monitoring my ZooKeeper container via JMX:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.port=9010
-Djava.rmi.server.hostname=0.0.0.0
-Dcom.sun.management.jmxremote.ssl=false

So the difference would be this entry -Dcom.sun.management.jmxremote.rmi.port which is fix the RMI port to be the same as JMX port.

With this I can just docker run -p 9010:9010 ... and everything is fine for me.

How to establish JMX connection to JVM running in docker : Adam , How to establish JMX connection to JVM running in docker (running in a docker container) you will have to activate remote JMX The following two parameters completely disable transport encryption and access control. See you at Java EE Microservices. and Tuning and troubleshooting Java EE 7  I am trying to remotely monitor a JVM running in docker. The configuration looks like this: machine 1: runs a JVM (in my case, running kafka) in docker on an ubuntu machine; the IP of this machine is 10.0.1.201; the application running in docker is at 172.17.0.85. machine 2: runs JMX monitoring

This does not work when you run that container in Docker machine - in VirtualBox. I am not sure what kind of address I should add to java.rmi.server.hostname because when I add there external IP of the Docker container I am connecting from my host, it does not work. So basically situation is like HOST ---> (MACHINE --- CONTAINER) and I can not reach it from HOST to CONTAINER.

Remote Java Debugging With Docker · Patrick McCarthy, But we're using Docker to run our Tomcat instance inside of a container. is running, but every time you try to connect to Tomcat via JConsole  The command docker inspect <container-id> provides more details about a running container, such as IP address. The command docker logs <container-id> will display messages the container has written to standard error or standard out. The command docker ps lists all the running containers.

I'm not sure if it's necessary but I would recommend adding this to your additional options -Djgroups.bind_addr=172.17.0.16. Also I'm pretty sure that this kind of options should probably go to CATALINA_OPTS and not JAVA_OPTS but that shouldn't make a difference. Another thing that I noticed is that the rmi server host name you defined is different than the one in the JMXServiceURL constructor. I'm no docker expert but shouldn't this be identical?

How to Enable JMX in Tomcat to Monitor & Administer, In this article, I will talk about how to enable and connect to Tomcat with JConsole​. I assume you have Tomcat installed if not; you can refer  Docker Tomcat Example - Dockerfile for Tomcat, Docker Tomcat Image. In this post, we are going to learn how to install a Tomcat Application Server or Web Container on Docker and Deploy web applications into the Tomcat running inside Docker.

This config worked for me:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.port=10005 
-Dcom.sun.management.jmxremote.rmi.port=10005 
-Djava.rmi.server.hostname=127.0.0.1 
-Dcom.sun.management.jmxremote.ssl=false

The important part was to to configure the rmi server hostname with the local loopback address. If i used 0.0.0.0 i wasn't able to reach the exposed port localy via an SSH Tunnel, with 127.0.0.1 everything worked fine.

Note: if you're running docker inside virtualbox things are different... you have to use the ip which virtualbox gives you here.

Monitoring and Managing Tomcat, If Tomcat is running as a Windows service, use its configuration -Dcom.sun.​management.jmxremote.access.file=. I'm running Geode (v1.14.0) servers/locators in Docker containers. I'm trying to run Pulse as a standalone WAR running in Tomcat in a Docker also. I can connect fine when running the Pulse WAR in

Need to expose both connector port and jmx port while running a docker image which is built by docker file.

docker run -it -p 8080:8080 -p 9997:9997 <build_tag> image_name

Where, 8080 is connector port and 9997 is jmx port which is being exposed as 9997 so that jmx client can connect to Tomcat mbeans.

Monitoring and Managing Tomcat, If Tomcat is running as a Windows service, use its configuration -Dcom.sun.​management.jmxremote.access.file=. Apache Tomcat is an open source implementation of the Java Servlet and JavaServer Pages technologies

Enable JMX RMI access to a docker container, Hi, my name is Alejandro and I'm trying to perform some profiling using JCM or JVM tools (included in java jdk). My application is running in a  Docker Container SSH Access. Since Docker containers don’t have the embedded GUI for their management, the most common way to take the full control over such an instance is connecting to it under the SSH protocol and perform any desired operations inside using the corresponding terminal commands.

JMX monitoring of multiple tomcat containers in Docker EE, Publishing the jmx ports and accessing via the host node address when the container running tomcat can be started up on any node i… When we run our Docker Tomcat image to create the container we map the ports we want forwarded from the Docker host to the container. For example, mapping 2022 to 22 for SSH (because we want to leave 22 for the Docker host), 8080 for Tomcat, 1898 for JMX, and 62911 for JDWP looks like:

JMX Monitoring for Java Application running on Docker (Apache , So it is not necessary that you have to explicitly do the docker pull . Step4: Run Docker Tomcat image as a container. Now the Image is ready and available in Docker Hub. Irrespective of, If the image is available locally or not. You can start the image as a container.

Comments
  • What happens if you leave out the -Djava.rmi.server.hostname=172.17.0.16 option? This option should offer a default value, Cf. stackoverflow.com/questions/10173834/…
  • Thanks. I use the following configuration and can monitor Tomcat via JMX. the field of rmi.port you suggested was added and hostname was set with external address, docker host's address. CATALINA_OPTS="${CATALINA_OPTS} -Xdebug -Xrunjdwp:transport=dt_socket,address=62911,server=y,suspend=n -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=9998 -Dcom.sun.management.jmxremote.rmi.port=9998 -Djava.rmi.server.hostname=10.70.1.5 -Dcom.sun.management.jmxremote.ssl=false"
  • This does not work when you run that container in Docker machine - in VirtualBox. I am not sure what kind of address I should add to java.rmi.server.hostname because when I add there external IP of the Docker container I am connecting from my host, it does not work. So basically situation is like HOST ---> (MACHINE --- CONTAINER) and I can not reach it from HOST to CONTAINER.
  • i reply to myself :) you have to set these properties: -Djava.rmi.server.hostname=$JAVA_RMI_SERVER_HOSTNAME -Dactivemq.jmx.url=service:jmx:rmi:///jndi/rmi://$JAVA_RMI_SERVER_HOSTNAME:$ACTIVEMQ_JMX_PORT/jmxrmi in such way that JAVA_RMI_SERVER_HOSTNAME address has to be set to external address of the Docker machine in case running in machine but it has to be set to external IP of the container itself when running in the native mode. Keep in mind that you have to export and map these ports from container to your local host.
  • 172.17.0.16 is internal address for docker's container. If a container doesn't have any settings, any clients outside the container can't connect to it. But, docker provides the functions that containers can expose some port and set a port mapping such as -p 18080:8080. Thus, I can use the URL 10.70.1.5:18080 to connect to the tomcat's root page running in the container.
  • I get this but I would expect you would use 127.0.0.1 cause as far as tomcat and rmi jmx are concerned, they are running on localhost. Which port they will be exposed on on the host machine is another story.