How to Run Apps Through HTTP in a Container

In this tutorial, you will see how you can run Maestro Framework apps inside a Docker container.
We will use Maestro Framework 2.0 for this tutorial.
Maestro Framework is just another .NET 8 application, so you just have to build a Docker image for that, include all the necessary files, and use the HTTP endpoint to start and monitor each Maestro app. The HTTP endpoint is provided in the Dacris.Maestro.Web project, an ASP.NET web API with a friendly forms designer and Swagger front-end. This tutorial requires that you know how to operate Docker and have worked with REST APIs before (with Swagger). Needless to say, Docker must be installed and working properly in order to run apps inside a container.

Step 1 - Build the Maestro LogicAppRunner

Download the Maestro Framework and use .NET 8 SDK to build the solution, as instructed in Docs/Readme.txt.

Step 2 - Copy the LogicAppRunner Binaries

Copy the contents of the Dacris.Maestro.Web folder to a new folder called ContainerImage.
Copy the LogicAppRunner.dll and all its dependencies from the LogicAppRunner/bin/Debug/net8.0 folder to the following subpath inside ContainerImage: Data/Maestro

Step 3 - Copy Your App

Copy the application or applications you wish to be able to run with Maestro to the ./Data/Apps folder inside ContainerImage. Make sure each application lives in its own folder with the folder name exactly the same as the application's executable .txt file. For example, if you have an app with logic inside LogicApp1.txt, make sure the folder name is LogicApp1. There is an example application here - OlispImport. The app produces output in Output.txt in the app folder. You can extract the example application into a new 'OlispImport' subfolder in ./Data/Apps.

Step 4 - Configure Your Database

We will run Firebird database inside a container to backup users inside Data/users.txt.
You can use a SQL Server database if you'd like. Here we will show you how to do it with Firebird.
First, create your container from the provided official image. Instructions are online at the Firebird website.
Please name your database 'Maestro.fdb'.
Once you've set up your database, make sure you get the container's IP address like so:
docker inspect <container_id>
Use 'docker ps' to list running containers.
Once you've got the IP address, you can create a connection string for Firebird.
Rename the Data/DbConfig_Sample.json file to Data/DbConfig.json.
Inside, you'll see a sample connection string. Replace the username and password with your values.
The database name and path should match what you created when you first ran the Firebird container.
In most cases, it will be /var/lib/firebird/data/Maestro.fdb. You need a full path to the fdb file as the Database value.
In the end, the connection string should look like this:
User ID=myusername;Password=mypassword;Database=/var/lib/firebird/data/Maestro.fdb;DataSource=127.0.0.1;
Replace '127.0.0.1' with the IP address of the Firebird container.

Step 5 - Build Your Maestro Web Docker Container Image

First, create your Dockerfile in the ContainerImage folder or download the Dockerfile provided as an example here.
Next, run the following command at the terminal, from the ContainerImage folder:
docker build -t maestro-image -f Dockerfile .

Step 6 - Create Your Docker Container

Now that you've got the container image created, the next step is to create your container.
Use the following command at the terminal:
docker create --name maestro-run maestro-image

Step 7 - Run the Maestro Web API

First, make sure that the Firebird container is up and running.
You can now start the container and the Maestro Web API using the following terminal command:
docker start maestro-run
(Later to stop it just run "docker stop maestro-run")

To access the API, we need to know what the IP address of our container is.
First, run the following terminal command:
docker ps

This will list all containers currently running. You can get your container ID from there.
Next, you need to run the following terminal command:
docker inspect <container_id>

From the console output, you should be able to find an IP address, like: 127.0.0.1

In your web browser, type http://<ip_address>:8080/swagger

You'll be able to use the Swagger UI to use the API.

Step 8 - Run Your App

The first thing you should do is to authenticate.
Maestro Web provides a few built-in API keys (license keys) in the Data/appkeys.txt file.
Use the /user POST endpoint to create a user (with password) based on one of the license keys.

To secure a production container, we recommend creating brand new app keys inside Data/appkeys.txt. Do not use the ones we provided for production.

Run the /auth/createToken endpoint with the username and password from the new user you created.
You will get back a JWT token. Copy this token (CTRL+C) and click the Authorize button at the top of the page.
Paste the token in the popup that shows up. Make sure you get rid of the quotes (").

Now that you've got yourself authenticated, you can run one of your apps.
Go to the /start endpoint and enter the app's name (case sensitive), e.g. OlispImport.
For syncOrAsync enter 'sync'.
Execute that endpoint.
Your app will run inside the container.
Note: You will receive a JSON as a response, with a certain runId for this app.
Each app in Maestro Web can have multiple runs, some running simultaneously, and all are self-contained and isolated.
Please copy the runId value as you'll need it for the next step.

Step 9 - Checking Output

If your app produces console output, unfortunately it will be hard to read from the container.
You will need to produce a file, at minimum, as your output.

Now, if your app does have a file as its output, you can grab that file from inside the container.
Just use the following terminal command on the host:
docker cp <containerId>:/file/path/within/container /host/path/target
In the case of our example OlispImport app:
docker cp <containerId>:/App/Data/Apps/<runId>/Output.txt ./out.txt

In production, we recommend that your app push output to HTTPS endpoints or upload files to SFTP/Azure Storage for ease of use and security. Maestro Framework makes it easy, as it provides built-in interactions for both HTTP(S) and SFTP. You can also have your app output files inside a 'Public' subfolder, and if you run the app with the form viewer - /viewer.html, you'll be able to download the output file. As an exercise, try going to /sampleform.html and you'll see some of the front-end capabilities of Maestro Web, v2.0.

Conclusions

Is running logic apps inside Docker containers the recommended way? In most cases, you can just run the apps locally as they should be fairly safe. However, if your app interacts with an AI or has any sort of agency where its logic can vary from what is specified in the .txt file, it is HIGHLY recommended that you run the app inside a container.

Also, if you wish to make your application executable remotely, from anywhere in the world, through an HTTPS endpoint, your best choice is to deploy it inside a container like shown in this tutorial. There are still hurdles to overcome with regards to making Maestro Framework CI/CD friendly, so for now you'll have to copy binaries (DLLs) as shown in this tutorial.

You may be able to get better CI/CD integration if you build LogicAppRunner from scratch and copy it over in your deployment pipeline. That is also an option.

Finally, please be mindful of the license restrictions of Maestro Framework, which (unless you've purchased a commercial license), do not allow for commercial uses.