React sample in Docker
Tutorial 2 📦
main - initial branch
dockerizing - final branch
dockerizing pull request - pull request with code changes
Overview​
In this second tutorial we describe the code improvements and the steps to follow in order to deploy the React sample application in Docker.

Prerequisites​
We recommend reading Docker documentation to get a base understanding of Docker's concepts and principles.
- First, you should go through previous tutorials OR clone main branch.
- JetBrains Rider or Visual Studio.
- Command prompt or Terminal.
In addition, you must download and install the latest version of Docker Desktop.
Backend​
The required changes in the backend are illustrated in this section. New files must be added, and some files must be modified to run React sample in Docker.
DatabaseUpgrade​
First, the backend should bring up the script for the database. This can be done by creating the class DatabaseUpgrade in the project
folder WorkflowApi. This class reads the SQL script from this directory, and it attempts to execute the script in the database. If the
execution process presents an exception, the operation will be repeated, a delay is done, and again the procedure for running the script is
executed. This is required because the database in the Docker container might start up after the backend application, and during this short
time it may be not available, so the exception allows to execute the start script several times to raise the database while it is not
successful.
using Microsoft.Data.SqlClient;
namespace WorkflowApi;
public class DatabaseUpgrade
{
private const int AttemptCount = 100;
private static readonly TimeSpan Delay = TimeSpan.FromSeconds(5);
private readonly string _connectionString;
private readonly string _sqlScript;
private DatabaseUpgrade(string connectionString, string sqlScript)
{
_connectionString = connectionString;
_sqlScript = sqlScript;
}
public static async Task WaitForUpgrade(string connectionString)
{
var sql = await File.ReadAllTextAsync("./Sql/CreatePersistenceObjects.sql");
var instance = new DatabaseUpgrade(connectionString, sql);
await instance.Upgrade();
await Console.Out.WriteLineAsync("The database has been upgraded");
}
private async Task Upgrade(int attemptNumber = 0)
{
try
{
await Console.Out.WriteLineAsync($"Upgrading database, attempt number: {attemptNumber}");
await UpgradeDatabase();
}
catch (Exception e)
{
await Console.Error.WriteLineAsync(e.Message);
if (attemptNumber >= AttemptCount) throw;
await Task.Delay(Delay);
await Upgrade(attemptNumber + 1);
}
}
private async Task UpgradeDatabase()
{
await using var connection = new SqlConnection(_connectionString);
await connection.OpenAsync();
await using var command = connection.CreateCommand();
command.CommandText = _sqlScript;
await command.ExecuteNonQueryAsync();
}
}
WorkflowApiConfiguration​
The WorkflowApiConfiguration was included to define the backend configuration. The Cors and LicenseKey will be set in the docker compose
file, so these settings are indicated in the configuration.
namespace WorkflowApi;
public class WorkflowApiConfiguration
{
public WorkflowApiCorsConfiguration Cors { get; set; }
public string LicenseKey { get; set; }
}
public class WorkflowApiCorsConfiguration
{
public List<string> Origins { get; set; }
}
CreatePersistenceObjects​
Next, in the Backend a directory called Sql and the SQL script CreatePersistenceObjects.sql must be added also in WorkflowApi
project to create the database objects according the Workflow Engine standard.
You can download the MS SQL database script here.
Then, set it in the location: Backend/WorkflowApi/Sql/CreatePersistenceObjects.sql.
Starting from Workflow Engine version 13.0.0, automatic migrations are now available, and scripts are no longer supported. For more information, see the documentation.