# Configuration

## Overview

This section explains how to completely configure a WorkflowGen container, including the `web.config` file, iisnode configuration for Node.js applications, database connection strings, etc. Everything is configurable via an environment variable except the license file, which is configured via a volume.

## WorkflowGen environment variables

WorkflowGen's image provides a number of specific environment variables that makes specific configurations possible. The following table provides descriptions of each of them:

<table data-header-hidden><thead><tr><th valign="top">Variable</th><th valign="top">Description &#x26; values</th></tr></thead><tbody><tr><td valign="top"><strong>Variable</strong></td><td valign="top"><strong>Description &#x26; values</strong></td></tr><tr><td valign="top"><code>WFGEN_ADMIN_USERNAME</code></td><td valign="top"><p>The username for the WorkflowGen Administrator account</p><p></p><p>Changing this value is useful when you're configuring this image with an OpenID provider. You can set it to a username that exists on the provider that you have access to. Then, when you browse to WorkflowGen, you can authenticate with it and it will log you in as an administrator. </p><p></p><p>For example, if you have a username on your provider named <code>foo@bar.com</code>, then you can set this environment variable to this username and authenticate with it in the container to have administrative access to WorkflowGen. <br><br>✏️ <strong>Note:</strong> If you change this, make sure to update the database as well.</p><p></p><p><strong>Possible values:</strong> <code>wfgen_admin</code> (default)</p></td></tr><tr><td valign="top"><code>WFGEN_DATABASE_CONNECTION_STRING</code></td><td valign="top"><p><strong>Required variable</strong></p><p><br>The connection string of the main database source<br></p><p>This environment variable must be present, or else the container will throw an error and exit.</p></td></tr><tr><td valign="top"><code>WFGEN_DATABASE_READONLY_</code><br><code>CONNECTION_STRING</code></td><td valign="top">The connection string of the read-only database source for a database setup with replicas</td></tr><tr><td valign="top"><code>WFGEN_AUTH_MODE</code></td><td valign="top"><p>This variable indicates which authentication method to be used by WorkflowGen</p><p></p><p><strong>Possible values:</strong></p><ul><li><code>adfs</code></li><li><code>application</code> (default)</li><li><code>auth0</code></li><li><code>azure-v1</code></li><li><code>basic</code></li><li><code>ms-identity-v2</code></li><li><code>okta</code></li><li><code>windows</code></li></ul></td></tr><tr><td valign="top"><code>WFGEN_GEN_APP_SYM_ENCRYPT_KEY</code></td><td valign="top"><p>Indicates whether or not the <code>ApplicationSecurityPasswordSymmetricEncryptionKey</code> should be generated if no value is provided</p><p></p><p>If <code>Y</code>, the <code>ApplicationSecurityPasswordSymmetricEncryptionKey</code> is regenerated when the container restarts. It is not compatible for usage in production because the secrets will be encrypted with different keys. Therefore, use <code>Y</code> only for developing or testing a single container scenario.</p><p></p><p><strong>Possible values:</strong> <code>Y</code> (default), <code>N</code></p></td></tr><tr><td valign="top"><code>WFGEN_LICENSE_FILE_NAME</code></td><td valign="top"><p>File name (including extension) of the license needed in the <code>C:\licenses</code> volume</p><p></p><p>If none is specified, the first file found is taken.</p></td></tr><tr><td valign="top"><code>WFGEN_START_SERVICE</code></td><td valign="top"><p>Indicates what the container should run</p><p></p><p>You can either run the WorkflowGen web application or Windows Services, or both. In a cluster, you'd probably want to have multiple containers in web app mode and only one container in Windows Services mode. You can also divide more by running multiple containers in web app mode, one container in engine mode, and one container in directory sync mode.</p><p></p><p><strong>Possible values:</strong></p><ul><li><code>all</code> (default)</li><li><code>dir_sync</code></li><li><code>engine</code></li><li><code>web_apps</code></li><li><code>win_services</code></li></ul></td></tr><tr><td valign="top"><code>WFGEN_MACHINE_KEY_VALIDATION_KEY</code></td><td valign="top"><p>Represents the <code>validationKey</code> property of the <code>machineKey</code> element in the <code>web.config</code> file</p><p></p><p>By default, IIS generates one when it isn't there. It's recommended to use this environment variable to share the machine key between instances of this container (e.g. in a web farm). See the <a href="https://support.microsoft.com/en-ca/help/2915218/resolving-view-state-message-authentication-code-mac-errors">Resolving view state message authentication code (MAC) errors</a> and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.web.configuration.machinekeysection?view=netframework-4.8">MachineKeySection Class</a> Microsoft articles for more details.</p></td></tr><tr><td valign="top"><code>WFGEN_MACHINE_KEY_DECRYPTION_KEY</code></td><td valign="top"><p>Represents the <code>decryptionKey</code> property of the <code>machineKey</code> element in the <code>web.config</code> file</p><p></p><p>By default, IIS generates one when it isn't there. It's recommended to use this environment variable to share the machine key between instances of this container (e.g. in a web farm). See the <a href="https://support.microsoft.com/en-ca/help/2915218/resolving-view-state-message-authentication-code-mac-errors">Resolving view state message authentication code (MAC) errors</a> and <a href="https://docs.microsoft.com/en-us/dotnet/api/system.web.configuration.machinekeysection?view=netframework-4.8">MachineKeySection Class</a> Microsoft articles for more details.</p></td></tr><tr><td valign="top"><code>WFGEN_MACHINE_KEY_VALIDATION_ALG</code></td><td valign="top"><p>Represents the validation property of the <code>machineKey</code> element in the <code>web.config</code> file</p><p></p><p>The algorithm name used to generate the validation key. <strong>Default:</strong> <code>HMACSHA256</code></p></td></tr><tr><td valign="top"><code>WFGEN_MACHINE_KEY_DECRYPTION_ALG</code></td><td valign="top"><p>Represents the decryption property of the <code>machineKey</code> element in the <code>web.config</code> file</p><p></p><p>The algorithm name used to generate the decryption key. <br><strong>Default:</strong> <code>AES</code></p></td></tr><tr><td valign="top"><code>WFGEN_DEPENDENCY_CHECK_INTERVAL</code></td><td valign="top"><p>Time between dependency check retries in milliseconds</p><p><strong>Default:</strong> <code>1000</code> (1 second)</p></td></tr><tr><td valign="top"><code>WFGEN_DEPENDENCY_CHECK_RETRIES</code></td><td valign="top"><p>Number of retries to attempt for each dependency check</p><p><strong>Default:</strong> <code>10</code></p></td></tr><tr><td valign="top"><code>WFGEN_DEPENDENCY_CHECK_ENABLED</code></td><td valign="top"><p>Indicates whether or not the dependency check should be done</p><p><strong>Possible values:</strong> <code>Y</code> (default), <code>N</code></p></td></tr><tr><td valign="top"><code>WFGEN_GRAPHQL_CORS_ENABLED</code></td><td valign="top"><p>Enables CORS headers for the GraphQL API</p><p><strong>Possible values:</strong> <code>Y</code> (default), <code>N</code></p></td></tr><tr><td valign="top"><code>WFGEN_GRAPHQL_CORS_ALLOWED_ORIGINS</code></td><td valign="top"><p>Comma-separated list of origins from which CORS will allow requests</p><p><strong>Default:</strong> <code>*</code></p></td></tr></tbody></table>

## Format-based environment variables

WorkflowGen's image also exposes various environment variables based on a specific format in order to configure more generic elements.

### `web.config`

In WorkflowGen, the `web.config` file is the main point of configuration. Since a container is by definition ephemeral, any changes made in the Configuration Panel would not persist between container restarts.&#x20;

In order to set configuration properties in the `web.config` file, you need to use a specific format for an environment variable that will contain the value of the property you want to set; this format is `WFGEN_APP_SETTING_<name>`.&#x20;

For example, if you want to set the `ApplicationUrl` property in the `web.config` to `https://mycorporation.com/wfgen`, you would set the  `WFGEN_APP_SETTING_ApplicationUrl=https://mycorporation.com/wfgen` environment variable  in the container.

#### 📌 Example with the `run` command

```
docker container run `
    # ...
    --env 'WFGEN_APP_SETTING_ApplicationUrl=https://mycorporation.com/wfgen' `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

For a list of `web.config` parameters and their descriptions and possible values, see the [Web and Application Configuration Parameters](https://docs.advantys.com/docs/tech/appendix-web-and-application-configuration-parameters) appendix in the [WorkflowGen Technical Guide](https://docs.advantys.com/docs/tech/).

### iisnode configuration for Node.js applications

You can also set specific iisnode properties for each Node.js application. To do this, you need to set an environment variable with the following format: `WFGEN_IISNODE_<node name>_<property name>`.&#x20;

* Replace `<node name>` with the name of the Node.js application (`AUTH`, `HOOKS`, `GRAPHQL`, or `SCIM`).
* Replace `<property name>` with the name of the property you want to set for the `<iisnode/>` XML node in the specific Node.js application's `web.config` file.

For example, if you want to set the iisnode `loggingEnabled` property in the Auth application to `true`, you would set the environment variable `WFGEN_IISNODE_AUTH_loggingEnabled=true`.

#### 📌 Example with the `run` command

```
docker container run `
    # ...
    --env WFGEN_IISNODE_AUTH_loggingEnabled=true `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

### Special iisnode options for Node.js applications

There are some special options that you can enable for each Node.js application by setting an environment variable that has the following template: `WFGEN_ENABLE_IISNODE_OPTION_<node app name>`. Then, you replace `<node app name>` with the name of the Node.js application (`AUTH` for example) and the value must be one of the following:

<table data-header-hidden><thead><tr><th valign="top">Value name</th><th valign="top">Description</th></tr></thead><tbody><tr><td valign="top"><strong>Value name</strong></td><td valign="top"><strong>Description</strong></td></tr><tr><td valign="top"><code>exposelogs</code></td><td valign="top"><p>Exposes the logs of the application through http. They will then be available at <code>https://example.com/wfgen/auth/iisnode</code> if the chosen Node.js application is <code>AUTH</code>. </p><p></p><p>✏️ <strong>Note:</strong> This option is for debugging purposes only. It is not recommended to use it in production.</p></td></tr></tbody></table>

### Trace configuration

You can activate .NET tracing for different WorkflowGen components using environment variables. Use the `WFGEN_TRACE_<component>_<option>=<value>` template with `<component>` as the name of the component you want to set the option on, `<option>` as the name of the option you want to set, and `<value>` as the value of the option.

#### Available components

* `WEB_APPS` (web applications)
* `ENGINE` (engine service)
* `DIR_SYNC` (directory synchronization service)
* `NODE` (Node.js components)

#### Options

<table data-header-hidden><thead><tr><th valign="top">Name</th><th valign="top">Description</th></tr></thead><tbody><tr><td valign="top"><strong>Name</strong></td><td valign="top"><strong>Description</strong></td></tr><tr><td valign="top"><code>LEVEL</code></td><td valign="top"><p>Controls the amount of information traced and therefore written in files</p><p></p><p><strong>Possible values:</strong></p><ul><li><code>ActivityTracing</code></li><li><code>All</code></li><li><code>Critical</code></li><li><code>Error</code></li><li><code>Information</code></li><li><code>Off</code> (default)</li><li><code>Verbose</code></li><li><code>Warning</code></li></ul><p>For more information on .NET tracing levels, see the <a href="https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.sourcelevels?view=netframework-4.8#fields">SourceLevels Enum</a> Microsoft article.</p></td></tr><tr><td valign="top"><code>INDENT</code></td><td valign="top"><p>Controls the indentation inside the trace logs</p><p></p><p><strong>Default value:</strong> <code>4</code> (maximum: <code>8</code>)</p></td></tr></tbody></table>

#### 📌 Example

To enable tracing for web applications with an indentation of `2` and only trace errors for the engine with an indentation of `0`, you would configure the environment variables as follows:

```
WFGEN_TRACE_WEB_APPS_LEVEL=Information
WFGEN_TRACE_WEB_APPS_INDENT=2
WFGEN_TRACE_ENGINE_LEVEL=Error
WFGEN_TRACE_ENGINE_INDENT=0
```

### Database configuration

#### Main connection string

The main connection string can be configured via the `WFGEN_DATABASE_CONNECTION_STRING` environment variable. You can put any string in this variable and its value will be put in WorkflowGen's `web.config` file at the `MainDbSource` connection string.

Here's how to specify the connection string with the `run` command:

```
docker container run `
    # ...
    --env WFGEN_DATABASE_CONNECTION_STRING=SomeConnectionString `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

#### Read-only connection string

If you have a read-only replica, you can configure it in the container as well. You can specify it with the `WFGEN_DATABASE_READONLY_CONNECTION_STRING` environment variable. It will be added to WorkflowGen's `web.config` file as a new entry in the connection strings with the name `ReadOnlyDbSource`.

Here's how to specify the read-only connection string with the `run` command:

```
docker container run `
    # ...
    --env WFGEN_DATABASE_CONNECTION_STRING=SomeConnectionString `
    --env WFGEN_DATABASE_READONLY_CONNECTION_STRING=SomeReadOnlyConnectionString `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

#### Custom connection strings

You can also configure more connections to custom data sources if you need to. They can be configured using a specific environment variable format: `WFGEN_CUSTOM_CONNECTION_STRING_<name>=<connection_string>`.&#x20;

For example, if you want a data source named `MyDataSource` with the connection string value of `MyConnectionString` in the WorkflowGen `web.config`, you would specify the following environment variable: `WFGEN_CUSTOM_CONNECTION_STRING_MyDataSource=MyConnectionString`.

#### 📌 Example with the `run` command

```
docker container run `
    # ...
    --env WFGEN_DATABASE_CONNECTION_STRING=SomeConnectionString `
    --env WFGEN_DATABASE_READONLY_CONNECTION_STRING=SomeReadOnlyConnectionString `
    --env WFGEN_CUSTOM_CONNECTION_STRING_MyDataSource=MyConnectionString `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

### Secrets

When using an orchestrator such as Kubernetes, you'll probably want to secure secrets using their built-in secret management tools. Follow the specific guide for your orchestrator to know how to create a secret.

For Kubernetes, see <https://kubernetes.io/docs/concepts/configuration/secret/>.

It's recommended to inject secrets into WorkflowGen containers as files because they won't be exposed as environment variables and they'll be removed from the container when it's stopped or removed.

{% hint style="info" %}
Secrets management is only possible using an orchestrator.
{% endhint %}

In order to get the secret value in the file, you need to suffix any environment variable you want to get the value of this way with `_FILE` and set its value to the path of the file containing the secret. The container will then get the value in the file at the specified path and set the environment variable without the suffix with that value.

For example, let's say you want to set the license serial number in the `web.config` to `WFG-SOME-LICENSE-KEY` using the environment variable `WFGEN_APP_SETTING_ApplicationSerialNumber`, but you want to use a secret for the value. All you have to do is suffix the environment variable name with `_FILE` so it becomes `WFGEN_APP_SETTING_ApplicationSerialNumber_FILE`. Then, set the value of this variable to the path of the file containing the serial number.

#### 📌 Example with Docker Swarm orchestrator

```
# Create the secret for the license serial number
"WFG-SOME-LICENSE-KEY" | docker secret create ApplicationSerialNumber -

# Create the container service in Docker Swarm
docker service create `
    # ...
    --env WFGEN_APP_SETTING_ApplicationSerialNumber_FILE=C:\ProgramData\Docker\secrets\ApplicationSerialNumber `
    --secret ApplicationSerialNumber `
    # ...
    advantys/workflowgen:7.18.3-win-ltsc2019
```

For Kubernetes, you would create a ConfigMap that complements your secret like this:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: wfgen-config
data:
  WFGEN_APP_SETTING_ApplicationSerialNumber_FILE: C:\secrets\ApplicationSerialNumber
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: wfgen-secret
data:
  # "V0ZHLVNPTUUtTElDRU5TRS1LRVkK" is the base64-encoded value of "WFG-SOME-LICENSE-KEY"
  ApplicationSerialNumber: 'V0ZHLVNPTUUtTElDRU5TRS1LRVkK'

```

Then, you would map the ConfigMap as environment variables and mount the secret as a volume like this:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wfgen
spec:
  selector:
    matchLabels:
      # ...
  template:
    metadata:
      labels:
        # ...
    spec:
      containers:
        - name: wfgen
          image: advantys/workflowgen:7.18.3-win-ltsc2019
          # ...
          envFrom: # ConfigMap as environment variables
            - configMapRef:
                name: wfgen-config
          env:
            - name: WFGEN_START_SERVICE
              value: webapps
          # ...
          volumeMounts:
            # ...
            - mountPath: C:\secrets # Mount Secret as a volume
              readOnly: true
              name: secrets
      volumes:
        # ...
        - name: secrets # Mount Secret as a volume
            secret:
              secretName: wfgen-sec
```

## Configuring the authentication mode

{% hint style="info" %}
For all authentication modes, you need to set `WFGEN_APP_SETTING_ApplicationUrl` and `WFGEN_APP_SETTING_ApplicationSerialNumber` in order to avoid unwanted behaviors.
{% endhint %}

### Application authentication

In order to let WorkflowGen handle authentication and the storage of user passwords, you don't need to configure anything special in the container. Keep in mind that the default username for the WorkflowGen administrative account is `wfgen_admin`.

### Windows and Basic authentication

In order to make Windows or Basic authentication modes work, your host needs to be in an Active Directory forest. Creating a user account on the host for Basic authentication won't work, because the IIS web server inside the container will try to find a user account registered inside the container instead of the host. For this reason, you need Active Directory.

To configure your Docker host to work with Active Directory to authenticate users, follow the [Group Managed Service Account](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts) (gMSA) guide from Microsoft in its Windows Containers documentation.

Kubernetes supports gMSAs for Windows pods and containers as of version 1.18. See the [Configure GMSA for Windows Pods and containers](https://kubernetes.io/docs/tasks/configure-pod-container/configure-gmsa/) Kubernetes article for details on how to configure it. Keep in mind that not all cloud providers supports gMSAs with Kubernetes. For example, Azure Kubernetes Service doesn't support this feature.

{% hint style="warning" %}
You can't use Basic authentication with Kubernetes.
{% endhint %}

### Azure v1 and Microsoft Identity Platform

For these providers, there is no special configuration to do other than setting the `WFGEN_AUTH_MODE` variable. For configuration instructions, see the [WorkflowGen for Azure](https://docs.advantys.com/docs/azure) guide.

### Active Directory Federation Services (AD FS), Auth0, and Okta

For these providers, there is no special configuration to do other than setting the `WFGEN_AUTH_MODE` variable. For configuration instructions, see the [WorkflowGen Technical Guide](https://docs.advantys.com/docs/tech/).

## Configuring your license

In order to configure your license, you need to set a specific environment variable with your license and copy your license file into a volume exposed to the WorkflowGen container. To do this, you first need to create a license volume or have your license at a specific path.

### Create a volume

```
docker volume create licenses
```

This will create a volume at a specific path on your file system (typically `C:\ProgramData\Docker\volumes\licenses\_data`) managed by Docker. You can get the path to the volume by executing the following command:

```
docker volume inspect -f "{{.Mountpoint}}" licenses
```

Then, you need to copy your license file to this location:

```
Copy-Item C:\Path\To\WorkflowGen.lic $(docker volume inspect -f "{{.Mountpoint}}" licenses)
```

Now, you can run the WorkflowGen container like so:

```
docker container run `
    # ...
    --env WFGEN_APP_SETTING_ApplicationSerialNumber=YOUR-WFG-LIC-NUM `
    --mount "type=volume,src=licenses,dst=C:\wfgen\licenses,readonly" `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

### Use a specific path

Here, you'll provide a path that you control as a volume to the container. You only need to pass the path when you run WorkflowGen:

```
docker container run `
    # ...
    --env WFGEN_APP_SETTING_ApplicationSerialNumber=YOUR-WFG-LIC-NUM `
    --mount "type=bind,src=C:\Path\To\Your\Licenses,dst=C:\wfgen\licenses,readonly" `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

## Bringing the WorkflowGen website offline

You can bring the web applications inside WorkflowGen's container offline by executing a script embedded in the image. This is useful to ensure that the site is still available when you want to perform maintenance tasks on its data without anything new being written. With pure containers, you can execute the following command:

```
docker container exec -i wfgen powershell C:\set-state.ps1 Offline
```

With Kubernetes, you can use **kubectl**:

```
kubectl exec -i wfgen-pod -- powershell C:\set-state.ps1 Offline
```

{% hint style="info" %}
You must do this **for each WorkflowGen container** that is running. The recommended approach is to scale down the number of containers to one and execute the `set-state.ps1` script once.
{% endhint %}

If you browse to your WorkflowGen website, you'll see the default offline web page. You can customize this web page by adding your own HTML file at the path `<wfgen appdata>\Templates\server\offline.htm`. If this file is present, it will be taken instead of the default one. If you have a volume for WorkflowGen's data, you can execute the following script:

```
$offlinePath = ".\offline.htm"
$serverTemplatePath = [io.path]::Combine(
    $(docker volume inspect --format "{{ .Mountpoint }}" wfgdata),
    "appdata" , "Template", "server"
)

if (-not (Test-Path $serverTemplatePath)) {
    New-Item $serverTemplatePath -ItemType Directory -Force
}

Copy-Item $offlinePath $serverTemplatePath

```

You can bring the site back online by executing the following command:

{% tabs %}
{% tab title="Docker CLI" %}

```
docker container exec -i wfgen powershell C:\set-state.ps1 Online
```

{% endtab %}

{% tab title="kubectl" %}

```
kubectl exec -i wfgen-pod -- powershell C:\set-state.ps1 Online
```

{% endtab %}
{% endtabs %}

## Using an orchestrator

### Kubernetes

Kubernetes also has a built-in object called **ConfigMap** to manage pod configuration. See the [Configure a Pod to Use a ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/) Kubernetes article for more information and instructions on how to use it. You should use this object to configure environment variables for WorkflowGen.

You can also manage sensitive information by protecting it further in the orchestrator in a secure area. See the [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) Kubernetes article for more information and instructions on how to use it. You should use this object to protect sensitive information such as the WorkflowGen license key, usernames, passwords, cryptographic keys, API keys, etc.

## Using your own configuration files

In order to use your own configuration files, you should build your own WorkflowGen image using the WorkflowGen **onbuild** image variant. See the [Custom Image](https://docs.workflowgen.com/docker/workflowgen-image/custom-workflowgen-image) page in the WorkflowGen Image section for more information.

## Using an external configuration manager

Some popular configuration managers support Docker containers out-of-the-box. Here are a few links to their specific documentation to get you started:

### Chef

* [Docker Cookbook](https://supermarket.chef.io/cookbooks/docker)
* [Chef and Kubernetes](https://www.chef.io/solutions/chef-and-kubernetes/)

### Ansible

* [Ansible – Getting started with Docker](https://docs.ansible.com/archive/ansible/2.6/scenario_guides/guide_docker.html)
* [Manage Kubernetes (K8s) objects](https://docs.ansible.com/ansible/latest/collections/kubernetes/core/k8s_module.html)

### Puppet

* [How to run Puppet in Docker](https://www.puppet.com/blog/puppet-docker)
* [How to Install and Configure Kubernetes with the Puppet Kubernetes Module](https://www.puppet.com/blog/puppet-kubernetes)
