Mendix: enabling debugger in docker container

Viewed 129

we use Mendix for some of our custom-apps; we are getting ready to migrate from m2ee-tools to docker deplyments of on-premise systems. This is because Mendix drops support for m2ee-tools beginning with Centos/RHEL 8, and the latest supported Centos/RHEL 7 end of life is in about 2 years (June 2024).

We got stuck on one key point in our proof-of-concept scenario and need help:

How to enable/disable debugger in a Mendix app that is running in a docker container?

What we have already found:

  1. -e DEBUGGER_PASSWORD=”stringData”

We are aware of triggering the debugger at container’s startup by providing them with a variable DEBUGGER_PASSWORD="stringData", but then the debugger is enabled throughout the lifetime of this instance of container which is undesired.

  1. Partial knowledge: POST request is used to communicate with a debugger

From some in-depth analysys we have also found that the debugger is normally enabled on a running Mendix application by a POST request to a running app. However, we are currently unaware of what the message body is.

1 Answers

We have identified the answer. Since finding the answer was not trivial, the original question has been unanswered for 3 weeks, and has received an upvote, therefore I will add the answer to this thread so it is usefull in case other Mendix developers search for "docker" + "debugger".

The solution delivered in bash

A container parametrized and started using the following command:

docker run -it -p 8088:8080  \
    -e ADMIN_PASSWORD='ApplicationAdminPassword1'  \
    -e DATABASE_ENDPOINT='postgres://pgPassword:pgUser@192.168.0.1:5432/pgDbName'  \
    -e M2EE_PASSWORD='PasswordForAdministrativeTasks1'  \
    mendix/mendix-buildpack:v1.2

can have the debugger enabled like this:

curl -X POST -u 'MxAdmin:PasswordForAdministrativeTasks1'  \
     -H "Content-Type: application/json"  \
     -H "X-M2EE-Authentication: `echo -n 'PasswordForAdministrativeTasks1' | base64`"  \
     -H "Connection: close"  \
     -d '{"action": "enable_debugger", "params": {"password": "aRandomPassForDebugger1"}}' \
     localhost:8088/_mxadmin/; echo

and the debugger is available as normal, via the address http://applicationHostIP:8088/debugger/ using the pasword you have declared "aRandomPassForDebugger1". M2ee-tools seem to be using alphanumeric characters only (perhaps in order to avoid troubles with special caracters in certain contexts or situations) - in this case the password strength has to be obtained by lengthening it. M2ee-tools use more than 20 characters.

The second action can in fact be performed using a variety of tools, not ecesairly with curl.

Comments on the solution

Two manuals were helpful, but required some effort to "comsume" and be turned into a method for enabling the debugger. The manuals can be found at docs.mendix.com and at github.com/mendix.

As you can see, in order to communicate with the runtime, you need to send a POST message with simple auth and the additional headers. Mendix team has decided to migrate from an admin-port used by m2ee-tools to a service available in the docker container at "_mxadmin" directory of the application-provisioning web-end.

Pay attention to this part:

-H "X-M2EE-Authentication: `echo -n 'PasswordForAdministrativeTasks1' | base64`"

It is a header with base64-encoded password (yes, the same password provided again in the same POST message, just provided in a different form). You can substitute the inline (that calculates base64) with the off-line-made string, which in this example is UGFzc3dvcmRGb3JBZG1pbmlzdHJhdGl2ZVRhc2tzMQ== .

Note that the message's paylod is a json data structure. Many payload-actions require only the "action" clause, but some other additionaly require parameters (like enable_debugger).

Actions related to the topic

  • enable_debugger '{"action": "enable_debugger", "params": {"password": "aStrongPass"}}'
  • get_debugger_status '{"action": "get_debugger_status"}'
  • disable_debugger '{"action": "disable_debugger"}'
  • get_admin_action_info '{"action": "get_admin_action_info"}'

The last listed action (get_admin_action_info) has a potential to be particularily useful for figuring out many other actions for communicating with the runtime-messaging (it returns a list of available actions), so try it out yourself.

Related