# File Management

## Overview

This section shows which persistent data are exposed and where. It also recommends some ways to persist, share, and back up the data. For backup strategies and recommendations, see the [Business Continuity & Disaster Recovery](https://docs.workflowgen.com/docker/business-continuity-and-disaster-recovery) section.

## Persistent data in WorkflowGen

There are three elements that must be persisted in WorkflowGen: the `App_Data` folder, the `wfapps` web application folder, and the SQL data. The first two are grouped in the same file share for simplicity and ease of use. To deploy a database, see the [SQL Server Hosting Options](https://docs.workflowgen.com/docker/sql-server-hosting-options) section.

The other two are files from WorkflowGen, and the reasons they must be persisted through a file share is explained in the [Architecture](https://docs.workflowgen.com/docker/architecture) section.

Additionally, you must have a file share with a valid WorkflowGen license in it so that the container can pick it up. Those folders must be exposed to the WorkflowGen containers through volumes. For more information about Docker volumes, see the [Volumes](https://docs.docker.com/storage/volumes/) Docker article.

<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>C:\wfgen\data</code></td><td valign="top"><p>This path contains all of the WorkflowGen data, including the <code>App_Data</code> folder and all the workflow applications created within WorkflowGen (e.g. in the <code>wfapps</code> folder).</p><p></p><p>The <code>wfapps\webforms</code> folder is mounted as a web application in IIS. </p></td></tr><tr><td valign="top"><code>C:\wfgen\licenses</code></td><td valign="top"><p>This path contains custom licenses that you want for WorkflowGen. The container will take the first one that it detects. It's recommended to put only one license in this directory to avoid licensing problems. </p><p></p><p>If you don't have a trial license, don't forget to set the <code>WFGEN_CONFIG_ApplicationSerialNumber</code> environment variable according to your license.</p></td></tr></tbody></table>

## Particularity of Windows Containers

Volumes are handled differently with Windows Containers compared to Linux Containers. The permission model changes and is different depending on whether you use process isolation or Hyper-V isolation. Before continuing with the procedures in this section, you should read the [Container Storage Overview](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/container-storage#persistent-volumes) Microsoft article.

Essentially, you must ensure that WorkflowGen containers can read and write to the `wfgdata` volume and read from the licenses volume. The group in the container that will access the volumes is named `IIS_IUSRS`.

## Recommended ways to persist

### Local file system path on the Docker host

This is the simplest way to persist WorkflowGen files with the containers. It consists of creating a local volume or using a bind mount on your Docker host that will retain the files after a container is removed. Volumes are the preferred way to persist files versus bind mounts because they're managed by Docker. This method doesn't scale well across multiple Docker hosts, however, so other methods should be considered in this case.

#### Volumes

To create a volume for each data path in the container, execute the following command:

```
"wfgdata", "licenses" | ForEach-Object { docker volume create $_ }
```

Then, you need to copy (or move) your license file to the licenses volume by executing the following command:

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

Now, you can run WorkflowGen container with those volumes to persist the data.&#x20;

#### 📌 Example of a `run` command

```
docker container run `
    # ...
    --mount "type=volume,src=wfgdata,dst=C:\wfgen\data" `
    --mount "type=volume,src=licenses,dst=C:\wfgen\licenses,readonly" `
    # ...
    advantys/workflowgen:7.18.3-win-ltsc2019
```

You have now successfully persisted WorkflowGen's files.

#### Bind mounts

Remember that you manage bind mounts manually. They are specific paths on the Docker host that you control. To use bind mounts as volumes, you only need to pass the paths when you execute the run command like so:

```
docker container run `
    # ...
    --mount "type=bind,src=C:\some\path\to\wfgdata,dst=C:\wfgen\data" `
    --mount "type=bind,src=C:\some\path\to\wfgen\licenses,dst=C:\wfgen\licenses,readonly" `
    # ...
    advantys/workflowgen:7.16.0-win-ltsc2019
```

### Network file share

You can use an SMB file share with Windows Containers such as Azure Files. Concretely, you connect the share to the Docker host and then mount it like a bind mount to containers; this is called an SMB mount. You can read more about SMB mounts in the [Container Storage Overview](https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/container-storage#persistent-volumes) Microsoft article.

### Using an orchestrator

#### Kubernetes

In Kubernetes, you'll use a **Persistent Volume** object to specify a place where Kubernetes will put data from pods. For more information about persistent volumes, see the [Persistent Volumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) page on the Kubernetes website.

Concretely, for WorkflowGen, you'll have to configure a volume that can handle the permission `ReadWriteMany` for the WorkflowGen data volume because multiple pods at the same time will access this volume to read and write data. Typically, to do this, you'll have to create a storage claim on the cluster like so:

```yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wfgdata-pvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: azurefile
  resources:
    requests:
      storage: 50Gi

```

In this example, the claim references a **Storage Class**, but you can reference a persistent volume directly, or other cloud-specific storage services depending on the cloud provider. Here, the `azurefile` storage class is provided by Azure Kubernetes Service. The allocation of the storage will be done automatically by the service. It will create a storage account with a file share that has 50 GB capacity.

## Pickup directory

If you configure WorkflowGen to use a pickup directory for notifications, you'll also need to specify a volume in order to expose the notifications to other services that will process them.&#x20;

The default path for the pickup directory is `C:\inetpub\mailroot\Pickup`. You can change it by supplying the `WFGEN_APP_SETTING_ApplicationSmtpPickupDirectory`  environment variable with any path inside the container. Then, you'll need to create a volume for the files like so:

```
docker volume create pickup
```

You can now map this volume to the configured pickup directory:

```
docker container run `
    # ...
    --env WFGEN_APP_SETTING_ApplicationSmtpDeliveryMethod=PickupDirectory `
    --env WFGEN_APP_SETTING_ApplicationSmtpPickupDirectory=C:\inetpub\mailroot\Pickup `
    --mount "type=volume,src=pickup,dst=C:\inetpub\mailroot\Pickup" `
    # ...
    advantys/workflowgen:7.18.3-win-ltsc2019
```

At this point, you could deploy another container with your service to take care of the notifications and bind the same volume to share the notification files.
