This is a more realistic, full setup of Community with Docker Compose and no debug services, host bind mounts, antivirus, external SQL server, email, and more.
For a more full-featured and scalable environment, consider using a Kubernetes cluster for hosting these containers instead of Compose. That is beyond the scope of this documentation. Hosting with Verint already provides auto-scaling via Kubernetes.
Prerequisites
What This Uses
Save the following sample Docker Compose files:
compose.yml:
name: community
x-common-variables: &common-variables
# Note: The following credentials are for development and testing purposes only.
# Use strong passwords in production and consider using secrets management for sensitive information
MSSQL_HOST: database
MSSQL_SA_USER: SA
MSSQL_SA_PASSWORD: T3ll1g3nt
MSSQL_APP_USER: community_user
MSSQL_APP_PASSWORD: T3ll1g3nt
DB_FORCE_UPGRADE: ${DB_FORCE_UPGRADE:-false}
APP_DB_NAME: ${APP_DB_NAME:-community_app}
REPORTING_DB_NAME: ${REPORTING_DB_NAME:-community_reporting}
ADMIN_USERNAME: admin
ADMIN_PASSWORD: p
ADMIN_EMAIL: admin@example.com
x-app-variables: &app-variables
EVOLUTION_CONFIGURATION_SOURCES: file=~/communitySettings.json;file=/community/config/compose.settings.json;env;command
networks:
community:
name: community-net
services:
web:
image: af1.verintconnect.com/dfe-community/community/web:14.0.0.644
restart: unless-stopped
networks:
- community
ports:
- 8080:8080
read_only: true
tmpfs:
- /tmp
volumes:
- ./data/cfs:/app/cfs
- ./config/settings.json:/community/config/compose.settings.json:ro
environment:
<<: *app-variables
healthcheck:
test: ["CMD", "/app/tools/healthcheck"]
start_period: 20s
interval: 60s
timeout: 10s
retries: 5
depends_on:
database:
condition: service_healthy
search:
condition: service_healthy
antivirus:
condition: service_healthy
installer:
condition: service_completed_successfully
cfs-init:
condition: service_completed_successfully
job:
image: af1.verintconnect.com/dfe-community/community/job:14.0.0.644
restart: unless-stopped
networks:
- community
read_only: true
tmpfs:
- /tmp
volumes:
- ./data/cfs:/app/cfs
- ./config/settings.json:/community/config/compose.settings.json:ro
environment:
<<: *app-variables
healthcheck:
test: ["CMD", "/app/tools/healthcheck"]
start_period: 20s
interval: 60s
timeout: 10s
retries: 5
depends_on:
database:
condition: service_healthy
search:
condition: service_healthy
antivirus:
condition: service_healthy
installer:
condition: service_completed_successfully
cfs-init:
condition: service_completed_successfully
database:
image: mcr.microsoft.com/mssql/server:2022-CU20-ubuntu-22.04
restart: unless-stopped
networks:
- community
ports:
- 5433:1433
volumes:
- ./data/sql:/var/opt/mssql
environment:
<<: *common-variables
ACCEPT_EULA: Y
healthcheck:
test: >-
/opt/mssql-tools18/bin/sqlcmd -C -S localhost -U SA -P "$$MSSQL_SA_PASSWORD" -Q "SELECT 1" || exit 1
interval: 10s
timeout: 3s
retries: 10
start_period: 10s
search:
image: af1.verintconnect.com/dfe-community/community/search:14.0.0.619
restart: unless-stopped
networks:
- community
ports:
- 5983:8983
volumes:
- ./data/solr:/var/solr
environment:
CORE_CONTENT: telligent-content
CORE_CONVERSATIONS: telligent-conversations
healthcheck:
test: >-
curl -s -A 'healthcheck' http://localhost:8983/solr/$$CORE_CONTENT/admin/ping?wt=json | grep -q '"status":"OK"'
start_period: 15s
interval: 10s
timeout: 5s
retries: 3
infra:
image: af1.verintconnect.com/dfe-community/community/infra:14.0.0.644
restart: unless-stopped
networks:
- community
ports:
- 5700:8080
read_only: true
tmpfs:
- /tmp
environment:
INFRA_Cache_MemoryLimitMegabytes: 500
INFRA_MessageBus_MaxLengthBytes: 102400
INFRA_MessageBus_IdleSeconds: 60
INFRA_Metrics_EnableOtlp: true
INFRA_Metrics_EnableConsole: false
INFRA_Metrics_OtlpEndpointProtocol: grpc
INFRA_Metrics_OtlpEndpoint: http://telemetry:18889/
INFRA_Logging_EnableOtlp: true
INFRA_Logging_EnableConsole: false
INFRA_Logging_OtlpEndpointProtocol: grpc
INFRA_Logging_OtlpEndpoint: http://telemetry:18889/
INFRA_Logging_MinimumLevel: Information,Microsoft.AspNetCore:Warning
healthcheck:
test: ["CMD", "/app/tools/healthcheck"]
start_period: 20s
interval: 60s
timeout: 10s
retries: 5
telemetry:
image: mcr.microsoft.com/dotnet/aspire-dashboard:9.3.0
restart: unless-stopped
networks:
- community
ports:
- 5888:5888
- 5317:18889
environment:
ASPNETCORE_URLS: http://+:5888
smtp:
image: axllent/mailpit:v1.27
restart: unless-stopped
networks:
- community
ports:
- 5825:8025
- 5025:1025
installer:
image: af1.verintconnect.com/dfe-community/community/installer:14.0.0.644
networks:
- community
environment:
<<: *common-variables
depends_on:
database:
condition: service_healthy
restart: true
antivirus:
image: clamav/clamav-debian:1.4.3
restart: unless-stopped
networks:
- community
ports:
- 5310:3310
healthcheck:
test: ["CMD-SHELL", "echo 'PING' | nc -w 5 localhost 3310"]
interval: 30s
timeout: 10s
retries: 5
# Ensure file storage volume is owned by
# app user (1654) of the web and job services
cfs-init:
image: alpine:3.22.1
volumes:
- ./data/cfs:/app/cfs
networks:
- community
entrypoint: chown -R 1654:1654 /app/cfs
settings.json:
{
"Core": {
"DisableEmail": false,
"SiteUrl": "http://localhost:8080",
"ApplicationPort": 8080
},
"ConnectionStrings": {
"SiteSqlServer": "server=database;uid=community_user;pwd=T3ll1g3nt;Trusted_Connection=no;TrustServerCertificate=True;database=community_app",
"Reporting": "server=database;uid=community_user;pwd=T3ll1g3nt;Trusted_Connection=no;TrustServerCertificate=True;database=community_reporting"
},
"CentralizedFileStorage": {
"RootPath": "/app/cfs"
},
"Search": {
"SolrContentUrl": "http://search:8983/solr/telligent-content/",
"SolrConversationsUrl": "http://search:8983/solr/telligent-conversations/"
},
"PluginEnablement": {
"Telligent.Evolution.Infra.Connector.InfraPlugin, Telligent.Evolution.Infra.Connector": true,
"Telligent.Evolution.Api.Plugins.FileValidators.ClamAvFileValidator, Telligent.Evolution.Platform": true
},
"PluginConfiguration": {
"Telligent.Evolution.Infra.Connector.InfraPlugin, Telligent.Evolution.Infra.Connector:host": "http://infra:8080",
"Telligent.Evolution.Api.Plugins.FileValidators.ClamAvFileValidator, Telligent.Evolution.Platform:host": "antivirus",
"Telligent.Evolution.Api.Plugins.FileValidators.ClamAvFileValidator, Telligent.Evolution.Platform:port": 3310
},
"Tracing": {
"EnableOtlp": true,
"OtlpEndpointProtocol": "grpc",
"OtlpEndpoint": "http://telemetry:18889/"
},
"Metrics": {
"EnableOtlp": true,
"OtlpEndpointProtocol": "grpc",
"OtlpEndpoint": "http://telemetry:18889/"
},
"Logging": {
"EnableOtlp": true,
"OtlpEndpointProtocol": "grpc",
"OtlpEndpoint": "http://telemetry:18889/"
}
}
They provide:
- One Web container
- One Job container
- Containerized SQL Server
- Search, Infra, Installer, ClamAV for antivirus, and Aspire Dashboard for telemetry
- Bind mounts for persisted data
- Direct HTTP access to
webon port8080
Prepare a Working Directory
Create a directory for the stack with the sample files:
community/
compose.yml
config/
settings.json
data/
sql/
cfs/
solr/
Bind Mounts
Named volumes are easy for a quick start. Bind mounts are often better when you need to:
- Inspect or replace SQL, CFS, or Solr data from the host
- Have easier ability to back up state
- Keep configuration files under your own directory layout
The above structure defines physical paths for SQL, CFS, and Solr data bind mounts. Those locations are reflected in compose.yml's services' volume mounts, such as the following snippet where ./data/cfs matches the structure above relative to the location of compose.yml. If you use different locations for SQL, CFS, and Solr data, update their corresponding paths within compose.yml.
Credentials
Adjust any user names or passwords for database and application accounts at the top of compose.yml as you see fit.
Non-Containerized SQL Server
Using containerized SQL Server is the easiest option, but you can also use an external database.
Edit compose.yml:
MSSQL_HOST: <SQL_DATABASE_SERVER>
MSSQL_SA_USER: <SQL_ADMIN_USER_NAME>
MSSQL_SA_PASSWORD: <SQL_ADMIN_PASSWORD>
MSSQL_APP_USER: community_user
MSSQL_APP_PASSWORD: <COMMUNITY_USER_PASSWORD>
APP_DB_NAME: community_app
REPORTING_DB_NAME: community_reporting
When the installer container runs, it connects to the SQL host using SA to create or update the app and reporting databases, create the community user, and grant the proper permissions to the community user.
Connection Strings
Ensure SQL credentials are also updated in settings.json's ConnectionStrings nodes.
Start the Stack
From the directory containing your customized compose.yml:
docker compose up -d --remove-orphans
On first startup, expect a longer wait while:
- Images are pulled
- SQL Server initializes
- Solr creates Community cores
- The installer creates or upgrades databases
Log in
After the stack is healthy, log in to Community at http://localhost:8080 with the admin username and password configured at the top of your compose.yml.
Endpoints
All endpoints made available:
- Community: http://localhost:8080
- SQL Server: localhost
,5433 - Telemetry dashboard: http://localhost:5888
- You can log in using the generated key written to Aspire's container's logs when it starts.
- MailPit: http://localhost:5825
- Solr admin: http://localhost:5983
Warning
If using this Compose stack in a production environment, remove port forwards for all of these services except for Community or ensure whatever reverse proxy is routing traffic to Community is not also exposing these other services.
What to Customize First
The sample settings.json is the main configuration layer mounted into web and job.
While logged in as an Administrator:
- Install a license
- Configure an outbound SMTP server
Configure telemetry and logging endpoints if you do not want local Aspire
Notes on Site URL, Host Names, and Proxying
The sample stack exposes a single web directly on port 8080. To modify this, customize the port or non-default host name by modifying Core:SiteUrl and Core:ApplicationPort in settings.json and the forwarded port for the web service in compose.yml. Restart the stack after these changes.
Add a local hosts entry for the custom host name. This provides host-based access only. TLS and standard web ports still need an external reverse proxy or TLS offloader.
If using a reverse proxy, you can add more web instances by copying and pasting the web service into a web2, web3, etc, with different forwarded ports. Routing to these nodes would defined by the reverse proxy.
Next Steps
While out of scope for this guide, Community images can be used with Kubernetes as well. Please review what container images make up Verint Community .