Production deployment
DThis section aims to provide information to deploy an instance for production usage by giving tips regarding best practices for configuration and highlighting some security aspects.
The following schema represents our recommended architecture with docker compose

This architecture is a standard example but may vary depending on your existing infrastructure and services like :
If you do not have a redis or database server, you can deploy one alongside beVault in the docker compose stack (see Local deployment for an example on how to deploy these components)
External services such as IAM solution, file transfer solution, API, … may be available in your private network and so secure connections may not be required
If you have multiple infrastructures or private networks, there is a possibility to deploy mutiple workers components on each infra or private networkwhich may prevent adpating firewall rules to allow connection to external data
Deployment
This example is designed to deploy only beVault components, all requirements and especially those described in the External solution requirements must be setup beforehand.
Create a directory to host the solution (
/opt/dfakto
,C:\Program Files\dFakto
, …)Create a file named
docker-compose.yml
with the following contentYAMLservices: states: image: quay.io/dfakto_org/states:${STATES_VERSION} container_name: states volumes: - states-data:/var/lib/dfakto-states environment: DFAKTO_STATES_STATECORE__REDISOPTIONS: "${REDIS_HOST}:${REDIS_PORT}" DFAKTO_STATES_STATECORE__AWSACCESSKEY: "${STATES_ACCESS_KEY}" DFAKTO_STATES_STATECORE__AWSSECRETKEY: "${STATES_SECRET_KEY}" DFAKTO_STATES_AUTHENTICATION__AUTHORITY: "${IDENTITY_SERVER_URL}" DFAKTO_STATES_AUTHENTICATION__CLIENTID: "${IDENTITY_SERVER_CLIENT_ID}" DFAKTO_STATES_AUTHENTICATION__AUDIENCE: "${IDENTITY_SERVER_CLIENT_AUDIENCE}" restart: unless-stopped workers: image: quay.io/dfakto_org/workers:${WORKERS_VERSION} container_name: workers environment: DFAKTO_WORKERS_STEPFUNCTIONS__authenticationKey: "${STATES_ACCESS_KEY}" DFAKTO_WORKERS_STEPFUNCTIONS__authenticationSecret: "${STATES_SECRET_KEY}" DFAKTO_WORKERS_STEPFUNCTIONS__serviceUrl: "http://states:5500" DFAKTO_WORKERS_STEPFUNCTIONS__EnvironmentName: "${WORKERS_ENVIRONMENT}" depends_on: - states volumes: - workers-data:/var/lib/dfakto-workers restart: unless-stopped metavault: image: quay.io/dfakto_org/metavault:${METAVAULT_VERSION} container_name: metavault environment: DFAKTO_METAVAULT_STEPFUNCTIONS__authenticationKey: "${STATES_ACCESS_KEY}" DFAKTO_METAVAULT_STEPFUNCTIONS__authenticationSecret: "${STATES_SECRET_KEY}" DFAKTO_METAVAULT_STEPFUNCTIONS__serviceUrl: "http://states:5500" DFAKTO_METAVAULT_AUTHENTICATION__AUTHORITY: "${IDENTITY_SERVER_URL}" DFAKTO_METAVAULT_AUTHENTICATION__CLIENTID: "${IDENTITY_SERVER_CLIENT_ID}" DFAKTO_METAVAULT_AUTHENTICATION__AUDIENCE: "${IDENTITY_SERVER_CLIENT_AUDIENCE}" DFAKTO_METAVAULT_AUTHENTICATION__ADMINEMAIL: "${ADMIN_EMAIL}" DFAKTO_METAVAULT_SERVERS__${DB_ENV_NAME}__NAME: "${DB_HOST}" DFAKTO_METAVAULT_SERVERS__${DB_ENV_NAME}__PORT: "${DB_PORT}" DFAKTO_METAVAULT_SERVERS__${DB_ENV_NAME}__DATABASETYPE: "${DB_TYPE}" DFAKTO_METAVAULT_SERVERS__${DB_ENV_NAME}__USERNAME: "${DB_RW_USER}" DFAKTO_METAVAULT_SERVERS__${DB_ENV_NAME}__PASSWORD: "${DB_RW_PASSWORD}" DFAKTO_METAVAULT_SERVERS__${DB_ENV_NAME}__READONLYUSERNAME: "${DB_RO_USER}" DFAKTO_METAVAULT_SERVERS__${DB_ENV_NAME}__READONLYPASSWORD: "${DB_RO_PASSWORD}" depends_on: - states volumes: - metavault-data:/var/lib/dfakto-metavault restart: unless-stopped metavault-ui: image: quay.io/dfakto_org/df2-ui:${METAVAULT_UI_VERSION} container_name: metavault-ui ports: - 8080:80 environment: METAVAULT_API_URL: http://metavault:5000 healthcheck: test: service nginx status || exit 1 interval: 10s timeout: 3s retries: 10 depends_on: - metavault restart: unless-stopped states-ui: image: quay.io/dfakto_org/states-ui:${STATES_UI_VERSION} container_name: states-ui ports: - 5500:80 environment: STATES_API_URL: http://states:5500 healthcheck: test: service nginx status || exit 1 interval: 10s timeout: 3s retries: 10 depends_on: - states restart: unless-stopped volumes: metavault-data: states-data: workers-data:
Adapt the configuration to your needs. All variables are indicated by this convention :
${VARIABLE}
and must be changed, see Advanced configuration for more information regarding expected values.Execute the command
docker compose up -d
in the directory where you create the fileCheck if containers are running correctly by executing
docker ps
command. The output should look like this (no restarting containers) :CODECONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5f5bccc5c143 quay.io/dfakto_org/workers:latest "/app/dFakto.States.…" 6 minutes ago Up 6 minutes (healthy) workers 772c65e05f8a quay.io/dfakto_org/metavault:latest "dotnet dFakto.DataV…" 6 minutes ago Up 6 minutes (unhealthy) metavault b52f195907fb quay.io/dfakto_org/df2-ui:latest "/docker-entrypoint.…" 6 minutes ago Up 6 minutes (healthy) 0.0.0.0:8080->80/tcp metavault-ui 9b4efd0f766e quay.io/dfakto_org/states:latest "dotnet dFakto.State…" 6 minutes ago Up 6 minutes (unhealthy) states a1e3495b071a quay.io/dfakto_org/states-ui:latest "/docker-entrypoint.…" 6 minutes ago Up 6 minutes (healthy) 0.0.0.0:5500->80/tcp states-ui
Configuration
The docker-compose.yml file above only contains mandatory configuration keys to run beVault, to have more information regarding the configuration of each component, you can refer to the Advanced configuration section of the documentation.
Metavault, States and workers components support 2 different ways for configuration :
Environment variables
Json files
Environments variables can be defined directly in the docker-compose.yml file or in a separate .env file, as explained in the docker compose official documentation : https://docs.docker.com/compose/environment-variables/set-environment-variables/.
Json configuration files requires several adaptations regarding the
Create a directory per component (example:
/opt/dfakto/config/{component}
)Create one or multiple json files with the component configuration. Example for metavault :
states.json
JSON{ "stepFunctions": { "authenticationKey": "${STATES_ACCESS_KEY}", "authenticationSecret": "${STATES_SECRET_KEY}", "serviceUrl": "http://states:5500", } }
openid.json
JSON{ "Authentication": { "AdminEmail": "${ADMIN_EMAIL}", "Authority": "${IDENTITY_SERVER_URL}", "ClientId": "${IDENTITY_SERVER_CLIENT_ID}", "Audience": "${IDENTITY_SERVER_CLIENT_AUDIENCE}" } }
dv-server.json
JSON{ "Servers": { "${DB_ENV_NAME}": { "Name": "${DB_HOST}", "Port": "${DB_PORT}", "DatabaseType": "${DB_TYPE}", "Username": "${DB_RW_USER}", "Password": "${DB_RW_PASSWORD}", "ReadOnlyUsername": "${DB_RO_USER}", "ReadOnlyPassword": "${DB_RO_PASSWORD}" } } }
Remove the environment section and mount the config directory to the related container in the
docker-compose.yml
file. Example for metavault :YAMLservices: metavault: image: quay.io/dfakto_org/metavault:${METAVAULT_VERSION} container_name: metavault depends_on: - states volumes: - metavault-data:/var/lib/dfakto-metavault - /opt/dfakto/config/metavault:/var/lib/dfakto-metavault/config restart: unless-stopped volumes: metavault-data:
Best practices
Do not use
latest
version because you may upgrade your application (with the commanddocker compose pull
for example) and miss some important steps to perform during a specific upgrade. We recommend using a specific number for each component and update regularly.By default, logs are not persisted (only exposed on the standard console, available with
docker logs
command) and are lost each time the container restart. We recommend adapting the logs configuration to persists them in files and mount a volume to ensure these files are persisted on the host. Example for metavault :YAMLmetavault: image: quay.io/dfakto_org/metavault:${METAVAULT_VERSION} container_name: metavault environment: DFAKTO_METAVAULT_Serilog__WriteTo__0__Args__outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}" DFAKTO_METAVAULT_Serilog__WriteTo__0__Args__theme: "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console" DFAKTO_METAVAULT_Serilog__WriteTo__0__Name: "Console" DFAKTO_METAVAULT_Serilog__WriteTo__1__Args__fileSizeLimitBytes: "10000000" DFAKTO_METAVAULT_Serilog__WriteTo__1__Args__path: "/var/log/metavault/log.txt" DFAKTO_METAVAULT_Serilog__WriteTo__1__Args__retainedFileCountLimit: "10" DFAKTO_METAVAULT_Serilog__WriteTo__1__Args__rollingInterval: "Day" DFAKTO_METAVAULT_Serilog__WriteTo__1__Args__rollOnFileSizeLimit: "True" DFAKTO_METAVAULT_Serilog__WriteTo__1__Name: "File" depends_on: - states volumes: - metavault-data:/var/lib/dfakto-metavault - metavault-logs:/var/log/metavault restart: unless-stopped volumes: metavault-data: metavault-logs:
Security
Even if it’s not mandatory we strongly recommend setting an SSL reverse proxy ahead of beVault application to encrypt all incoming HTTP requests. More information here : NGINX Proxy & HTTPS
We recommend also to activate an encryption mechanism on your database server