mendix with supervisord/daemontools

Hi there, We are looking to start Mendix service via supervisord or daemontools, that will start and monitor the JavaVM during reboots etc. For that, we will need to start/run the mendix script that will output stdout/etc and NOT-fork into the background, and will respond to SIGHUP/SIGTERM/SIGQUIT to terminate "nicely". Using m2ee just start and returns to the console after is forked and daemonized the application into the background. Advice/dierections/URLs I've missed in my Binging of Google? Update Yes I know m2ee does something "similar" to supervisord, but I'm actually in need of supervisord's inside supervisord (ie. I have the main supervisord that startups at boot time, and then for each "cluster" I have another supervisord running, with it's mendix, it's nginx and postgresql, that way I can stop and start a cluster belonging to a user) Will need to spend time with the m2ee tools source code then.
3 answers

Have you considered checking out the source to m2ee-tools?


We use the same scripts to run stuff on our cloud: we have a layer of init scripts on top of m2ee-tools to restart on server reboot. Additionally, you can use m2ee as either a lib or a CLI to talk to the mendix runtime, asking for statistics or to perform a Health Microflow (which the devs can configure in the modeler). This should allow you to do all the monitoring and sysadminning you want :)

As to your question to run directly under supervisord or systemd: I don't believe we have support for that OOB, in our infrastructure we've always run with init scripts that need to grab config from an external source anyway, so we needed some custom layering there.

I'd probably suggest you do one of three things:

  1. go into the source and figure out how to stop the forking. This is really going against the grain though, and not really how stuff was intended to work from Mendix's point of view.
  2. treat m2ee as a library, you can import a whole bunch of functions that allow you to talk to the runtime, start, stop, etc etc. Python is actually pretty easy to pick up and quite pleasant to use :)
  3. grab m2ee and use it as a cli, write some custom scripts in bash that wrap the calls and go from there.

Well, actually m2ee fullfills a similar role as supervisord does, except it backgrounds the process, writes a pid file and then connects to the admin port to configure it and fully start the application (you can see that happening viewing the trace logging when doing m2ee -vvv), (the pid file is actually only used as a backup to be able to kill the process later if the admin port of the JVM gets unresponsive).

Starting m2ee from supervisord is like starting supervisord (or start-stop-daemon) from supervisord. It does not really make sense. supervisord is meant to be used with dumb processes which do not implement backgrounding, and do not close their stdin/stdout when they start.

m2ee is also designed to be used by an unprivileged user account instead of being started from init scripts or supervisord (that's what customers ask for, they want to have a tool that does not require their application development team to have root access), and that's why it does the double-forking-backgrounding itself that you would otherwise do from an init script or systemd.

I think it would be possible to rewrite m2ee so that it would not exit the intermediary process in the double-fork and keep the process group intact, while still running the second part of application initialization in the first process (which is attached to supervisord), but doing so sounds a bit like the work needed to make supervisord run in supervisord itself. You'd have to make the whole process group work correctly with signals (so supervisord stop does not just kick away the m2ee process and leaves the JVM running) and stdin/stdout behaviour, which will get messy. It's certainly fun to try, but I never did before, because it was built for another use case, namely that the user account that has to control the application is always an unprivileged user account.

The ideal thing for supervisord would be to start the JVM process directly (instead of having m2ee in between, which has the same purpose), but in that case you would have to know the exact environment and command to provide (and figuring that out is exactly what m2ee does) and afterwards implement something else that connects to the admin port and does the second half of the start procedure (which is also what m2ee is doing for you).

If you just want to have the app started again after reboot, you can put an @reboot m2ee start inside the crontab of the local user account. Sounds dirty, but it does the job. Stopping can be implemented by calling m2ee -y stop as the user account, which will first try to shut down the application in a nice way using the admin API, and if that's not possible because the JVM is heap spacing like crazy or got unresponsive for some other reason it will resort to sending signals like SIGTERM/SIGQUIT to make it stop in a "not nicely" way.