Install with Docker

This guide explains how to install and deploy the Nextcloud Exchange Connector application using Docker.

Pre-requirements

Before deploying the application, make sure the following dependencies already exist and are reachable by the connector:

  1. The Nextcloud service account details are available (Nextcloud configuration guide)

  2. The Exchange service account or app registration details are available (Exchange configuration guide)

  3. A supported database is available and reachable from the application

Which databases are supported?
  1. Docker is installed on your machine (Docker official installation guide)

Installation Guide

Step 1. Prepare the docker-compose.yml file

We provide an example of docker-compose.yml file that you can edit to match your specifications. This example defines one primary service instance and optional secondary service instances.

  • The primary instance uses Service__IsPrimary=true

  • All secondary instances use Service__IsPrimary=false

  • Secondary_Replicas_Amount controls how many secondary instances are created

If secondary instances are not required, remove the secondary.sendent.synchronization.service section from the configuration file.

version: '3.8'
 
services:
# SendentSynchronizer
primary.sendent.synchronization.service:
#image: rg.nl-ams.scw.cloud/sendent-public/sendent-sync:latest
image: sendent-sync-local:latest
# deploy:
# resources:
# limits:
# memory: 4G # Memory limiting per Instance
# reservations:
# memory: 1G # Memory reservation per Instance
build:
context: .
dockerfile: Dockerfile
restart: on-failure
environment:
# Nextcloud Configuration
- Service__NextcloudConfiguration__NextcloudBaseUrl
- Service__NextcloudConfiguration__NextcloudServiceUsername
- Service__NextcloudConfiguration__NextcloudServicePassword
- Service__NextcloudConfiguration__SharedSecret
 
# Exchange Configuration
- Service__ExchangeConfiguration__ExchangeType
- Service__ExchangeConfiguration__ExchangeOnPremUrl
- Service__ExchangeConfiguration__ExchangeOnPremDomain
- Service__ExchangeConfiguration__ExchangeOnPremAdfsAuthorityUrl
- Service__ExchangeConfiguration__ExchangeTenantId
- Service__ExchangeConfiguration__ExchangeAdminRaw
- Service__ExchangeConfiguration__ExchangeAdminFile
 
# Database Configuration
- DatabaseConfiguration__DatabaseType
- DatabaseConfiguration__DatabaseEncryptionKey
- DatabaseConfiguration__ConnectionString
 
# Concurrency Configuration
- Service__ConcurrencyConfiguration__MaxParallelProcessingUsers
- Service__ConcurrencyConfiguration__MaxUsersPerAdmin
 
# Service Configuration
- Service__IsPrimary=true
- Service__DefaultWorkerName
- Service__BatchLimit
- Service__WorkerIntervalSeconds
- Service__SyncIntervalInSeconds
- Service__CriticalSyncIntervalInSeconds
- Service__BatchSaveSize
- Service__StartWeekend
- Service__SyncMode
- Service__SyncType
 
# Full Synchronization Configuration
- Service__FullSyncConfiguration__ProcessAttachments
 
# Sensitive Synchronization Configuration
- Service__SensitiveSyncConfiguration__SensitiveTitle
- Service__SensitiveSyncConfiguration__SensitiveCategory
 
# Logging Configuration
- Serilog__MinimumLevel__Default
 
- Service__LoggingConfiguration__LogsOutput
- Service__LoggingConfiguration__LogDirectoryPath
- Service__LoggingConfiguration__LogFileSizeLimit
- Service__LoggingConfiguration__LogFileAmountLimit
# Configuration for Loki
- Service__LoggingConfiguration__LokiInternalUrl
 
# Configure correct ENVIRONMENT if needed
- ASPNETCORE_ENVIRONMENT
 
volumes:
- sendent-logs:/app/logs
- ./exchangeAdmins:/app/settings
 
secondary.sendent.synchronization.service:
#image: rg.nl-ams.scw.cloud/sendent-public/sendent-sync:latest
image: sendent-sync-local:latest
deploy:
replicas: ${Secondary_Replicas_Amount:-1} # Amount of instances
# resources:
# limits:
# memory: 4G # Memory limiting per Instance
# reservations:
# memory: 1G # Memory reservation per Instance
build:
context: .
dockerfile: Dockerfile
restart: on-failure
environment:
# Nextcloud Configuration
- Service__NextcloudConfiguration__NextcloudBaseUrl
- Service__NextcloudConfiguration__NextcloudServiceUsername
- Service__NextcloudConfiguration__NextcloudServicePassword
- Service__NextcloudConfiguration__SharedSecret
 
# Exchange Configuration
- Service__ExchangeConfiguration__ExchangeType
- Service__ExchangeConfiguration__ExchangeOnPremUrl
- Service__ExchangeConfiguration__ExchangeOnPremDomain
- Service__ExchangeConfiguration__ExchangeOnPremAdfsAuthorityUrl
- Service__ExchangeConfiguration__ExchangeTenantId
- Service__ExchangeConfiguration__ExchangeAdminRaw
- Service__ExchangeConfiguration__ExchangeAdminFile
 
# Database Configuration
- DatabaseConfiguration__DatabaseType
- DatabaseConfiguration__DatabaseEncryptionKey
- DatabaseConfiguration__ConnectionString
 
# Concurrency Configuration
- Service__ConcurrencyConfiguration__MaxParallelProcessingUsers
- Service__ConcurrencyConfiguration__MaxUsersPerAdmin
 
# Service Configuration
- Service__IsPrimary=false
- Service__DefaultWorkerName
- Service__BatchLimit
- Service__WorkerIntervalSeconds
- Service__SyncIntervalInSeconds
- Service__CriticalSyncIntervalInSeconds
- Service__BatchSaveSize
- Service__StartWeekend
- Service__SyncMode
- Service__SyncType
 
# Full Synchronization Configuration
- Service__FullSyncConfiguration__ProcessAttachments
 
# Sensitive Synchronization Configuration
- Service__SensitiveSyncConfiguration__SensitiveTitle
- Service__SensitiveSyncConfiguration__SensitiveCategory
 
# Logging Configuration
- Serilog__MinimumLevel__Default
 
- Service__LoggingConfiguration__LogsOutput
- Service__LoggingConfiguration__LogDirectoryPath
- Service__LoggingConfiguration__LogFileSizeLimit
- Service__LoggingConfiguration__LogFileAmountLimit
# Configuration for Loki
- Service__LoggingConfiguration__LokiInternalUrl
# Configure correct ENVIRONMENT if needed
- ASPNETCORE_ENVIRONMENT
 
volumes:
- sendent-logs:/app/logs
- ./exchangeAdmins:/app/settings
depends_on:
primary.sendent.synchronization.service:
condition: service_started
 
volumes:
sendent-logs:
driver: local

Step 2. Prepare the settings.env file

At a minimum, provide valid values for:

  • Service Configuration

  • Database Configuration

  • Nextcloud Configuration

  • Exchange Configuration

  • Exchange Administrator Credentials

We provide an example of settings.env file that you can edit to match your specifications.
To understand the meaning of each parameter in settings.env refer to the Configuration guide.

# Service Configuration
Service__IsPrimary=true
# Deployment Types: Container(0), Binary(1)
Service__DeploymentType=0
Service__DefaultWorkerName="SendentWorker"
Service__BatchLimit=50
Service__WorkerIntervalSeconds=120
Service__SyncIntervalInSeconds=60
Service__CriticalSyncIntervalInSeconds=100
Service__BatchSaveSize=100
Service__StartWeekend=6
# Synchronization Modes: None(0), Calendars(1), Contacts(2), Tasks(4)
# You can combine modes, just place sum of necessary numbers in this property
Service__SyncMode=1
# Synchronization Types: Full(0), Sensitive(1)
Service__SyncType=1
# Database Configuration
# Allowed Database types: Postgres(0), SqlServer(1), MariaDB(2), MySql(3)
DatabaseConfiguration__DatabaseType=0
DatabaseConfiguration__DatabaseEncryptionKey=YourSuperSecretKey123!
DatabaseConfiguration__ConnectionString=Host=postgres_db;Port=5432;Database=SendentDB;Username=postgres;Password=YourPassword123
# Postgres Example:
Host=localhost;Port=5432;Database=SendentDB;Username=postgres;Password=YourPassword123
# Postgres Example:
Host=postgres_db;Port=5432;Database=SendentDB;Username=postgres;Password=YourPassword123
# SqlServer Example: Server=localhost;Database=SendentDB;UserId=sa;Password=YourStrong!Pass123;Encrypt=False;
# SqlServer Example: Server=mssql_db;Database=SendentDB;UserId=sa;Password=YourStrong!Pass123;Encrypt=False;
# MariaDB Example:
Server=localhost;Port=3306;Database=SendentDB;Uid=root;Pwd=YourPassword123
# MariaDB Example:
Server=maria_db;Port=3306;Database=SendentDB;Uid=root;Pwd=YourPassword123
# MySql Example:
Server=localhost;Port=3306;Database=SendentDB;Uid=root;Pwd=YourPassword123
# MySql Example:
Server=mysql_db;Port=3306;Database=SendentDB;Uid=root;Pwd=YourPassword123
# Nextcloud Configuration
Service__NextcloudConfiguration__NextcloudBaseUrl=https://cloud.example.com/
Service__NextcloudConfiguration__NextcloudServiceUsername=serviceAdmin
Service__NextcloudConfiguration__NextcloudServicePassword=abc
Service__NextcloudConfiguration__SharedSecret="abc"
# Exchange Configuration
# Allowed Exchange Types: Cloud(1), OnPremKerberos(2), OnPremBasicAuth(3), OnPremADFS(4)
Service__ExchangeConfiguration__ExchangeType=1
Service__ExchangeConfiguration__ExchangeOnPremUrl=https://outlook.office365.com/EWS/Exchange.asmx
Service__ExchangeConfiguration__ExchangeOnPremDomain=domain_test
# Fill in your administrator's credentials in the property below using necessary template for filling in
# Cloud: "[{\"AppId\":\"AppId1\", \"ClientSecret\":\"Secret1\"},{\"AppId\":\"AppId1\",\"ClientSecret\":\"Secret1\"}]"
# OnPrem(Kerberos/BasicAuth): "[{\"User\":\"Admin1\", \"Pass\":\"Password1\"}, {\"User\":\"Admin2\", \"Pass\":\"Password2\"}]"
# OnPremADFS: "[{\"ClientId\":\"ClientId1\", \"ClientSecret\":\"Secret1\" }, {\"ClientId\":\"ClientId2\", \"ClientSecret\":\"Secret2\"}]"
# Service__ExchangeConfiguration__ExchangeAdminRaw="[{\"AppId\":\"example \", \"ClientSecret\":\"example2\"}]"
# Service__ExchangeConfiguration__ExchangeAdminFile=
Service__ExchangeConfiguration__ExchangeAdminRaw=
Service__ExchangeConfiguration__ExchangeAdminFile=customAdmins.json
# Concurrency Configuration
Service__ConcurrencyConfiguration__MaxParallelProcessingUsers=10
Service__ConcurrencyConfiguration__MaxUsersPerAdmin=10
Secondary_Replicas_Amount=2
# Full Synchronization Configuration
Service__FullSyncConfiguration__ProcessAttachments=true
# Sensitive Synchronization Configuration
Service__SensitiveSyncConfiguration__SensitiveTitle="Busy"
Service__SensitiveSyncConfiguration__SensitiveCategory="Nextcloud Sync"
# Logging (Serilog & Loki)
# Change global Log level
Serilog__MinimumLevel__Default=Debug
#Change Logs output: None(0), Console(1), Database(2), File(4), Grafana(8)
# You can combine outputs, just place sum of necessary numbers in this property
Service__LoggingConfiguration__LogsOutput=5 # Console + File
Service__LoggingConfiguration__LogDirectoryPath=SendentLogs
# For Binary deployment Limits log's file size in MB
Service__LoggingConfiguration__LogFileSizeLimit=50
# For Binary deployment Limits amount of log files
Service__LoggingConfiguration__LogFileAmountLimit=20

Step 3 (optional). Prepare the admins.json file

Place the admin.json inside the local ./exchangeAdmins directory.

The credential payload format depends on the configured Exchange authentication type.
You can find more information regarding the admins.json file in the Exchange Setup Guide.

[
{
"ExchangeType": 1, // 1 = M365
"AppId": "your-app-id-1",
"ClientSecret": "your-client-secret-1"
},
{
"ExchangeType": 2, // 2 = Kerberos
"Username": "serviceaccount",
"Password": "your-password"
},
{
"ExchangeType": 4, // 4 = ADFS
"ClientId": "your-client-id-1",
"ClientSecret": "your-client-secret-1"
}
]

Step 4. Start the application

Run:

docker compose up -d

Step 5. Verify that the containers started

Run:

docker compose ps

Step 6. Check application logs

Run:

docker compose logs

If file logging is enabled, logs are also written under the mounted application logs directory.

Grafana & Loki Setup

If you enabled Grafana logging (included 8 in Service__LoggingConfiguration__LogsOutput), you must configure the following additional properties in your configuration file (.env) to ensure the application connects to the monitoring stack properly:

  • Service__LoggingConfiguration__LokiInternalUrl

Description: The internal URL used by the application containers to push logs to Loki.

Example: Service__LoggingConfiguration__LokiInternalUrl=http://loki:3100

  • GRAFANA_USER

Description: Your custom administrator username for logging into the Grafana dashboard.

Example: GRAFANA_USER="SuperAdmin"

  • GRAFANA_PASSWORD

Description: Your custom administrator password for the Grafana dashboard.

Example: GRAFANA_PASSWORD="SecretPassword"

How to Access Grafana and View Logs?

1. Open your web browser and navigate to http://localhost:3000 (or your server's IP address on port 3000).

2. Log in using the GRAFANA_USER and GRAFANA_PASSWORD configured in the .env file.


Was this article helpful?