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:
The Nextcloud service account details are available (Nextcloud configuration guide)
The Exchange service account or app registration details are available (Exchange configuration guide)
A supported database is available and reachable from the application
Which databases are supported?
PostgreSQL (PostgreSQL official installation guide)
Microsoft SQL Server (Microsoft SQL Server official installation guide)
MariaDB (MariaDB official installation guide)
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=trueAll secondary instances use
Service__IsPrimary=falseSecondary_Replicas_Amountcontrols 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 ConfigurationService__IsPrimary=true# Deployment Types: Container(0), Binary(1)Service__DeploymentType=0Service__DefaultWorkerName="SendentWorker"Service__BatchLimit=50Service__WorkerIntervalSeconds=120Service__SyncIntervalInSeconds=60Service__CriticalSyncIntervalInSeconds=100Service__BatchSaveSize=100Service__StartWeekend=6# Synchronization Modes: None(0), Calendars(1), Contacts(2), Tasks(4)# You can combine modes, just place sum of necessary numbers in this propertyService__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=0DatabaseConfiguration__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 ConfigurationService__NextcloudConfiguration__NextcloudBaseUrl=https://cloud.example.com/Service__NextcloudConfiguration__NextcloudServiceUsername=serviceAdminService__NextcloudConfiguration__NextcloudServicePassword=abcService__NextcloudConfiguration__SharedSecret="abc"# Exchange Configuration# Allowed Exchange Types: Cloud(1), OnPremKerberos(2), OnPremBasicAuth(3), OnPremADFS(4)Service__ExchangeConfiguration__ExchangeType=1Service__ExchangeConfiguration__ExchangeOnPremUrl=https://outlook.office365.com/EWS/Exchange.asmxService__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 ConfigurationService__ConcurrencyConfiguration__MaxParallelProcessingUsers=10Service__ConcurrencyConfiguration__MaxUsersPerAdmin=10Secondary_Replicas_Amount=2# Full Synchronization ConfigurationService__FullSyncConfiguration__ProcessAttachments=true# Sensitive Synchronization ConfigurationService__SensitiveSyncConfiguration__SensitiveTitle="Busy"Service__SensitiveSyncConfiguration__SensitiveCategory="Nextcloud Sync"# Logging (Serilog & Loki)# Change global Log levelSerilog__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 propertyService__LoggingConfiguration__LogsOutput=5 # Console + FileService__LoggingConfiguration__LogDirectoryPath=SendentLogs# For Binary deployment Limits log's file size in MBService__LoggingConfiguration__LogFileSizeLimit=50# For Binary deployment Limits amount of log filesService__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.