Skip to content

Run Multiple VMs with grisp_supervisor

Luca Succi edited this page Oct 10, 2025 · 9 revisions

Multiple VM support

We are currently using erlinit to boot Erlang and Elixir reelases on the target system.

Sadly, erlinit does not support running multiple releases. At the moment grisp_alloy can build and deploy multiple releases, but can only setup one to boot at system startup. To work around this limitation we designed grisp_supervisor, a simple Erlang app that can do this magic for us.

How to ship multiple projects

When building the firmware as described in build-firmware-update it is possible to list multiple projects. If you previoulsly built multiple projects, you can include all of them in the firmware build.

./build-project.sh $SYSTEM $PROJECT_1 
./build-project.sh $SYSTEM $PROJECT_2
./build-firmware.sh $SYSTEM $PROJECT_1 $PROJECT_2

In this case the firmware will contain all projects listed, but only the first one will be started automatically on boot, by erlinit.

Run multiple VMs with grisp_supervisor

grisp_supervisor is a simple OTP application made to supervise child BEAM virtual machines. To build the application, just clone the repository and build it as any grisp_alloy project.

git clone https://github.com/grisp/grisp_supervisor ./path/to/grisp_supervisor
./build-project.sh $SYSTEM ./path/to/grisp_supervisor

By default, grisp_supervisor is designed to fetch its configuration at runtime from the /etc/grisp_supervisor.config file. Since we are using grisp_alloy, we can easely provide such file without having to customize the grisp_supervisor project.

In the sample/overlay directory, you can find an example that allows you to test the grisp_supervisor.

This file: grisp_supervisor.config contains some basic config to run the hello_grisp and hello_elixir sample applications by running 2 VMs in parallel.

Testing with sample projects

./build-project.sh grisp2 hello_grisp
./build-project.sh grisp2 hello_elixir
./build-project.sh grisp2 ./path/to/grisp_supervisor
./build-firmware.sh grisp2 -n test -o samples/overlay grisp_supervisor hello_grisp hello_elixir

This will create a firmware that will run grisp_supervisor with hello_grisp and hello_elixir installed on the side. The firmware filesystem will also have the /etc/grisp_supervisor.config file in place, thanks to the overlay path we provided. This allows grisp_supervisor use such information to start the BEAM releases.

Note that with our example you will have 3 BEAM processes locally connected via Erlang Distribution protocol:

  • 1 VM with grisp_supervisor
  • 1 VM with hello_grisp
  • 1 VM with hello_elixir

grisp_supervisor supports various settings, please consult the grisp_supervisor Readme to learn all the available options.

Things to consider for development

When opening a console to the device, you will land into the Erlang shell of grisp_supervisor. From here, the simplest way to can interact with the child VMs is via RPC calls.

(grisp_supervisor@kmx8mm-00000000)> nodes().
['hello_grisp@kmx8mm-00000000',
 'hello_elixir@kmx8mm-00000000']

(grisp_supervisor@kmx8mm-00000000)> rpc:call('hello_elixir@kmx8mm-00000000', 'Elixir.IO', puts, ["ciao"]).
ciao
ok

Keep in mind that all standard output of the child VMs will be printed in the grisp_supervisor shell. This happens because all processes in the child VMs will inherit the group_leader of grisp_supervisor.