Running Magnolia in a Docker container is a normal and quite popular deployment choice. At the moment we ourselves do that e.g. for the UI tests. However, troubleshooting the instance performance isn't a trivial thing. Here are a couple of pointers re: how to attach common Java profilers to a process inside of a container. Note: most of the problems occur with Docker for Mac (vs Linux version), since on Macos Docker still runs non-natively on top of a Hyperkit vm, complicating the remote access from the local java processes to the container.

JProfiler

Attaching JProfiler to a java process in container is relatively easy. All that is required is to attach JProfiler agent to the process and expose the relevant port. This github gist pretty much covers it. Here's how our typical Dockerfile for the UI tests will look like with JProfiler setup:

Dockerfile with JProfiler agent
FROM tomcat:9.0.11-jre8

RUN wget http://download-aws.ej-technologies.com/jprofiler/jprofiler_linux_10_0_1.tar.gz -P /tmp/ && \
        tar -xzf /tmp/jprofiler_linux_10_0_1.tar.gz -C /usr/local &&\
        rm /tmp/jprofiler_linux_10_0_1.tar.gz

EXPOSE 8849

COPY ./magnolia-ee-integration-tests/tests/target/wars/ /usr/local/tomcat/webapps/

ENV CATALINA_OPTS="-Xmx2G -Dmagnolia.update.auto=true -agentpath:/usr/local/jprofiler10.0.1/bin/linux-x64/libjprofilerti.so=port=8849"

RUN touch /usr/local/tomcat/logs/build-log.out

RUN echo "done"
Note that for some reason in order to successfully attach JProfiler to the process, the container needs to be started with -p 8849:8849. \

Note that tomcat process will initially hang and will wait for JProfiler session to attach (maybe use docker logs -f for clarity).


VisualVM

VisualVM connects to a remote JVM via RMX connection and needs a proper setup (e.g. prertty well laid out here: darksideofthedev.com/java-profiling-with-visualvm-in-docker-container/). The biggest obstacle especially on the macs is the address of the rmi server: it is not possible out of the box to communicate directly from macos host to the running HyperKit vm and causes tedious hassle. However, one can specify 0.0.0.0 as rmi server, which will enable all the interfaces for connection. The eventual JVM startup properties might look like:

-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