14.12.0 14.11.0 14.10.0 14.9.0 14.8.0 14.7 14.6 14.5 14.4 14.3
14.12.0 14.11.0 14.10.0 14.9.0 14.8.0 14.7 14.6 14.5 14.4 14.3

Installation Guide


Internet should be available on the machine where the application is being installed, and connections on port 9242 should be allowed in the network firewall to carry out the installation steps.

All the commands start with a #, indicating that root user privileges are required to execute these commands. Trailing # is not a part of the command.

Requirements for HA Deployment

  • Replay Server for HA Deployment

  • Database for VRS metadata + Keycloak — PostgreSQL (supported from VRS 14.10.0) or SQL Server 2019–2022

  • Two SIP Trunks for HA

  • VRS solution on two separate machines for HA

  • Keycloak for authentication:

    • EFCX: EFCX Server (Keycloak/IAM)

    • Cisco: deploy a separate Keycloak (shared by both VRS HA nodes; do not use EFCX Keycloak)

FQDN Mapping for Multi-tenancy


There are two types of installation: EFCX and Cisco (UCCX & UCCE). For EFCX, most of the steps are not required, as Keycloak, JtapiConnector, and Mixer are not required.

Allow ports in the firewall for VRS

If there is an active firewall, allow the following ports.

443/tcp
444/tcp
8088/tcp
5060/tcp (only for Cisco)
16386-32768/udp (only for Cisco)
8021/tcp
1433 /tcp
5432 /tcp


# Additional port to open in case of High Availability (HA)
8500
8300
8301 /tcp/udp
8302 /tcp/udp
8303 /tcp/udp
8600 /tcp/udp

Installation Steps

  1. Please make sure that Solution Prerequisites are met for the desired deployment type. 

  2. Download the deployment script deployment.sh and place it in the user’s home or any desired directory. This script will:

    1. Delete the recording-solution directory if it exists.

    2. Clone the required files for deployment

  3. To execute the script, give it permissions to execute and run it as follows.

    Bash
    $ chmod 755 deployment.sh                  
    $ ./deployment.sh
    

This command will clone the skeleton project: recording-solution. This recording-solution directory contains all the required files for deployment. It will be cloned in the same place as the deployment script is placed.

Now, our cloning has been completed. Our VRS files, deployment files, and directories have been downloaded. We can proceed to configure it.

14.12.0: deployment.sh clones branch 14.12.0. If you clone the files yourself:

Bash
git clone -b 14.12.0 https://gitlab.expertflow.com/voice-recording-solution/recording-solution.git

Confirm with cd recording-solution && git branch --show-current — it should print 14.12.0.

  1. Follow this guide to install and configure Freeswitch. The recording path in Free SWITCH and in the Docker Compose volume must be the same.

  2. Follow this guide to configure ESL. (for Pause and Resume Recording)

  3. Follow this guide to create an application user on CUCM for JTAPI Connector.

  4. Create databases vrs and keycloak_vrs, then run the VRS schema on vrs only:

    • PostgreSQL (14.10.0+ / 14.11.0): run data/scripts/postgres.sql against database vrs (pgAdmin Query Tool or psql -h <db_host> -U <user> -d vrs -f data/scripts/postgres.sql). 14.11.0 adds hold_time and converts tag_id to an array so a call can have multiple tags.

    • SQL Server: run data/scripts/sqlserver.sql against database vrs (SSMS or sqlcmd). 14.11.0 stores tag_id as a JSON array and adds hold_time. Rename any leftover CallVariable1–10 columns to call_variable1–10.

    Leave keycloak_vrs empty — Keycloak creates its own tables. See also the VRS Upgrade Guide from 14.10.0 to 14.11.0.

    Cisco only: From VRS 14.12.0, the skeleton postgres.sql / sqlserver.sql scripts on vrs already include dual archival columns (archival_setting storage fields and related session stamps). Do not run the EFCX fusionpbx SQL on the Cisco vrs database. EFCX: apply the EFCX-only fusionpbx SQL later in this guide (before install-efcx.sh).

  5. Navigate to recording-solution/docker directory.

  6. Open the docker-compose-cisco.yml file.

    • For non-HA deployments: Uncomment the archival-process container and keep the consul container commented.

    • For HA deployments: Uncomment the consul container and keep the archival-process container commented.
      After making the changes, save and close the file.

  7. Open docker/config.env and set Keycloak database variables (do not hardcode these in docker-compose-cisco.yml): KC_DB, KC_DB_URL, KC_DB_USERNAME, KC_DB_PASSWORD.

    • PostgreSQL: KC_DB=postgres, KC_DB_URL=jdbc:postgresql://<db_host>:5432/keycloak_vrs

    • SQL Server: KC_DB=mssql, KC_DB_URL=jdbc:sqlserver://<db_host>:1433;databaseName=keycloak_vrs;encrypt=true;trustServerCertificate=true

    DB_ENGINE and KC_DB must match (postgres with postgres, or sqlserver with mssql).

  8. In the same config.env, set VRS metadata DB variables: DB_DRIVER, DB_ENGINE, DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD. PostgreSQL defaults (14.10.0): org.postgresql.Driver, postgres, 5432, vrs. For SQL Server use com.microsoft.sqlserver.jdbc.SQLServerDriver, sqlserver, 1433.

  9. Set KC_HOSTNAME in config.env to the recorder server IP/FQDN.

  10. Save and close config.env. Keycloak image in compose is 23.0.7 (prefer 23.0.7+).

  11. Run chmod 755 install-cisco.sh && ./install-cisco.sh. The script uses --env-file docker/config.env so Keycloak ${KC_*} values resolve. Verify Keycloak at http://<IP>:8088/auth.

    Security: Change the Keycloak admin console default password (admin / admin) before production use.

  12. Add the following KeyCloak variables in config.env for CISCO deployment only, using the keycloak setup guide. In the case of EFCX, these variables will be commented out.


Names

Description

1

KEYCLOAK_REALM_NAME

Usually VRS. Must match Keycloak realm exactly (case-sensitive). Follow Keycloak setup guide for a new realm.

2

KEYCLOAK_CLIENT_ID

Usually vrs. Must match Keycloak client.

3

KEYCLOAK_CLIENT_SECRET

From Keycloak → Clients → vrs → Credentials (follow Keycloak setup guide).

4

KEYCLOAK_URL

Internal URL for backend: http://keycloak:8080/

5

KEYCLOAK_ADMIN_USERNAME

Keycloak admin console user (default admin — change before production)

6

KEYCLOAK_ADMIN_PASSWORD

Keycloak admin console password (default admin — change before production)

7

KEYCLOAK_PERMISSION_GROUP

Usually AGENT_GROUP (Finesse gadget)

8

KC_HOSTNAME

Hostname Keycloak advertises (recorder IP/FQDN)

9

KC_DB

postgres or mssql — set in config.env (not compose)

10

KC_DB_URL

Full Keycloak JDBC URL for keycloak_vrs

11

KC_DB_USERNAME

Keycloak DB username

12

KC_DB_PASSWORD

Keycloak DB password

14.11.0 tagging: all users can view tags. Create the realm role evaluatetag and assign it to users who should assign or unassign tags on Media Recordings. The viewtag role is no longer required. See the Keycloak setup guide and VRS Authorization & Permissions.

  1. Open config.env in the same directory and update the environment variables given below.

Name

Description

1

VRS_URL

CISCO → URL of a local machine. example, https: //192.168.1.101

EFCX → Keep it as “http”

2

TZ

Time Zone. e.g, Asia/Karachi

3

LOCAL_MACHINE_IP

CISCO → Local machine IP. example 192.168.1.101 *

EFCX → FQDN that is mapped to Media Server IP (only used for on-prem Single Tenant deployment). For Multi-Tenant this variable will be commented out.

4

EFCX_FQDN

CISCO → This variable is no longer required for VRS 14.6.1 and later deployments; keep it commented out.

EFCX → FQDN of EFCX. e.g. https://FQDN. This variable is only used for Single Tenant (on-prem) Deployment

5

DEPLOYMENT_PROFILE

CISCO (for Cisco Contact Center)
EFCX (for Expertflow CX Contact Center)

6

PEER_ADDRESS

Add the IP or FQDN of the Second Recorder VM (For HA)

7

JTAPI_HA_MODE

Set it true for HA and false for Non-HA

8

SCREEN_RECORDING

If Screen recording is enabled, set it to true; otherwise, false

9

CONSUL_URL

(Only for CISCO HA) Add the IP address with port 8500 of the local machine http://192.168.1.101:8500

10

CISCO_TYPE

Type of CISCO, either UCCX or UCCE

11

DIRECTORY_PATH_TO_MONITOR

The path for the archival process to monitor should be the same path where sessions are kept, e.g, /var/vrs/recordings/cucmRecording/sessions/

12

FINESSE_URL

URL or FQDN of Finesse, e.g. https://uccx12-5p.ucce.ipcc:8445

13

RETRY_LIMIT

Limit to retry in case the connection fails. e.g 2

14

ARCHIVAL_PROCESS_NODE

active

15

CUCM_APPLICATION_USER_NAME

CUCM Application username that has been created in step 6.

16

CUCM_APPLICATION_USER_PASSWORD

Password for the CUCM Application User.

17

CUCM_IP

IP address of Call Manager

18

LICENSE_CHECKING

false (Keep it false)

19

NO_OF_DEL_DAYS

No of days after which the streams will be deleted

20

ENCRYPTION_ENABLED

Should be “true”

21

TEMP_MERGED_RECORDING_PATH

Add the complete path where files are created in the session folder. e.g. /var/vrs/recordings/cucmRecording/sessions/

22

ENABLE_AGENT_DOWNLOAD

Turns download capability on or off at the deployment level. Individual users still need the Keycloak download role; without that role the Download button stays hidden. See VRS Authorization & Permissions.

23

ENABLE_FINESSE_GADGET

This config is to enable/disable auto-login while VRS is embedded in Finesse as a gadget.

24

TRUST_STORE_PATH

Only if needed. Uncomment these and provide the path of the truststore dir which is ssl directory in the recording-solution.

25

TRUST_STORE_PASSWORD

Only if need. Uncomment it and Provide the password of the truststore.

26

COMPRESSION_ENABLED

Enable compression when using a Cisco profile. (True/False)

Also set these Cisco / archival variables in config.env:

Name

Description

ARCHIVAL_JOB_INTERVAL

Archival scheduler interval in hours (e.g. 8)

CALL_ID_FORMULA

Optional call-id formatting expression; leave empty for default

CISCO_WRAPUP_BACKFILL_ENABLED

true to enable mixer wrap-up / call-variable sync

CISCO_WRAPUP_SYNC_LAG_MIN

Minutes to wait after call end before reading wrap-up data (default 2)

CISCO_WRAPUP_SYNC_BATCH_SIZE

Max wrap-up rows processed per sync cycle (default 500)

Set display labels for Cisco call variables call_variable1–10 (UCCE TCD Variable1–10 / UCCX customvariable1–10). Change the text to match what your call variables hold:

Bash
CALL_VARIABLE1_LABEL=Customer Name
CALL_VARIABLE2_LABEL=Extension
CALL_VARIABLE3_LABEL=Account No.
CALL_VARIABLE4_LABEL=IVR Code
CALL_VARIABLE5_LABEL=Reference ID
CALL_VARIABLE6_LABEL=Customer Type
CALL_VARIABLE7_LABEL=Branch Code
CALL_VARIABLE8_LABEL=Service Type
CALL_VARIABLE9_LABEL=Priority Level
CALL_VARIABLE10_LABEL=Campaign/Source

The below Env variables are only for UCCX.

Name

Description

1

CCX_PRIMARY_IP

Primary UCCX IP address. e.g 192.168.1.33

2

CCX_SECONDARY_IP

Secondary UCCX IP, e.g, 192.168.1.33

3

CCX_ADMIN_USERNAME

CCX Admin username

4

CCX_ADMIN_PASSWORD

CCX Admin password

UCCX Informix CRA enrichment (14.12.0, opt-in) — Enable only when this UCCX deployment uses Informix CRA and you want the mixer to enrich wrap-up, CSQ/queue, hold time, and call variables from CRA. Leave disabled (default) for UCCE, or for UCCX without Informix CRA. Details: Cisco Wrap-up Codes and Call Variables.

In the same docker/config.env, set these mixer variables for Informix CRA (UCCX only):

Name

Description

UCCX_DB_ENGINE

Opt-in engine. Default / unset behaves as sqlserver (ODBC path). Set to informix to use Informix CRA over JDBC (port 1504 by default).

UCCX_DB_HOST

UCCX CRA database host (IP or hostname).

UCCX_DB_NAME

UCCX CRA database name.

UCCX_DB_USER / UCCX_DB_PASSWORD

CRA database credentials.

UCCX_DB_PORT

Optional. Default 1433 for sqlserver; default 1504 for informix.

UCCX_INFORMIX_SERVER

Required when UCCX_DB_ENGINE=informix. INFORMIXSERVER value for the JDBC URL — same value as cisco-connector CC_SERVER / DBeaver INFORMIXSERVER. Do not derive this from an IP-only host.

UCCX_INFORMIX_JDBC_JAR / UCCX_INFORMIX_BSON_JAR

Optional jar paths inside the mixer image. Defaults: /opt/informix/jdbc-15.0.0.2.jar and /opt/informix/bson-3.8.0.jar.

After changing these values, recreate/restart the mixer. Place a test UCCX call and confirm wrap-up / queue / hold / call variables after the usual sync delay.

The below Env variables are only for UCCE.

Name

Description

1

UCCE_IP

UCCE IP

2

UCCE_DATABASE

UCCE awdb database name

3

UCCE_USERNAME

UCCE awdb database user’s username

4

UCCE_PASSWORD

UCCE awdb database user’s password

  1. Add the Following environment variables for pause and resume recording.


Names

Description

1

ESL_HOST

IP address of the Recorder Machine

2

ESL_PORT

Port of the Record where ESL commonly used 8021

3

ESL_PASSWORD

Password of ESL

4

REC_PATH_STREAMS

Path where streams are saved, e.g, vrs/var/recordings/cucmRecording/streams

Update the Database environment variables in config.env.


Name

Description

1

DB_DRIVER

JDBC driver. PostgreSQL: org.postgresql.Driver. SQL Server: com.microsoft.sqlserver.jdbc.SQLServerDriver

2

DB_ENGINE

postgres or sqlserver (must match KC_DB: postgres or mssql)

3

DB_HOST

IP/FQDN of the VRS metadata database host

4

DB_NAME

VRS metadata database name (usually vrs). For EFCX, from /etc/fusionpbx/config.conf

5

DB_USER

VRS DB username. For EFCX, from /etc/fusionpbx/config.conf

6

DB_PASSWORD

VRS DB password. For EFCX, from /etc/fusionpbx/config.conf

7

DB_PORT

PostgreSQL: 5432. SQL Server: 1433

8

KC_DB

Keycloak DB vendor: postgres or mssql

9

KC_DB_URL

Full Keycloak JDBC URL. Postgres: jdbc:postgresql://<db_host>:5432/keycloak_vrs. SQL Server: jdbc:sqlserver://<db_host>:1433;databaseName=keycloak_vrs;encrypt=true;trustServerCertificate=true

10

KC_DB_USERNAME

Keycloak database username

11

KC_DB_PASSWORD

Keycloak database password

Update some additional variables for either CISCO or EFCX deployment.

Name

CISCO

EFCX

ROOT_DOMAIN

set it to “VRS” always

For Multitenant Deployment-> Root Domain of the VRS nginx, eg vrs.expertflow.com (value will be equal to tenantId for on-prem deployment).

TENANT_URL

Comment out not needed

CX Tenant url to fetch tenants, e.g., (https://tenant4.expertflow.com/cx-tenant/tenant)
We can add any of the FQDNs that are mapped in EFCX in place of TENANT_URL

CX_ROOT_DOMAIN

Comment out not needed

Root domain of the CX Solution, eg, (expertflow.com) (value will be “NIL“ for on-prem deployment)

  1. For EFCX Deployment Profile, the line <param name="url" value="http://127.0.0.1/app/xml_cdr/xml_cdr_import.php"/> in the xml_cdr.conf.xml file should be uncommented. Run the following command to open the xml_cdr.conf.xml and uncomment the above line.

nano /etc/freeswitch/autoload_configs/xml_cdr.conf.xml

Once the file is open, then uncomment the line and save it. Then restart the Freeswitch. systemctl restart freeswitch

  1. For EFCX Deployment profile: The root domain vrs.expertflow.com should be mapped to the IP address of the VRS server. Ask IT to configure this.

  2. Each tenant’s root domain should be routed to vrs.expertflow.com on port 444.

    For example, if we have two tenants — mtt01 and mtt02 — and the root domain is vrs.expertflow.com, then:

    This will make the VRS accessible at the following URLs:

  1. To update the self-signed certificates for VRS, get the public authority or domain signed certificate .crt and .key files, name them server.crt and server.key, and replace the files in /recording-solution/config/certificates with these two new files. Names should be the same.

  2. Navigate to the recording-solution directory and assign permissions to the install script.

  3. chmod 755 install-cisco.sh  #in case of CISCO
    chmod 755 install-efcx.sh   #in case of EFCX
    chmod 755 install-replay.sh #in case of HA CISCO
    
  4. Perform this step only if Deployment Profile is EFCX (VRS 14.12.0+). For Cisco, dual archival columns are already included when you run the skeleton data/scripts/postgres.sql or data/scripts/sqlserver.sql on database vrs earlier in this guide. EFCX uses the Media Server fusionpbx database instead — those ALTERs are not in the recording-solution skeleton, so run them manually here before starting the stack.

    On the Media Server, note the database password:

    cat /etc/fusionpbx/config.conf | grep database.0.password
    

    Connect to fusionpbx (enter the password when prompted; use your DB host if it is not local):

    psql -h 127.0.0.1 -p 5432 -U fusionpbx -d fusionpbx
    

    Run the following SQL (dual archival settings + CDR stamps):

    SQL
    -- EFCX / fusionpbx — dual archival settings + CDR stamps
    -- Run after connecting:
    --   psql -h <db_host> -p 5432 -U fusionpbx -d fusionpbx
    
    ALTER TABLE archival_setting
      ADD COLUMN IF NOT EXISTS storage_type VARCHAR(20) NOT NULL DEFAULT 'sftp';
    
    ALTER TABLE archival_setting
      ADD COLUMN IF NOT EXISTS sftp_server_ip   VARCHAR(255),
      ADD COLUMN IF NOT EXISTS sftp_username    VARCHAR(255),
      ADD COLUMN IF NOT EXISTS sftp_password    VARCHAR(255),
      ADD COLUMN IF NOT EXISTS sftp_folder_path VARCHAR(512),
      ADD COLUMN IF NOT EXISTS s3_endpoint      VARCHAR(255),
      ADD COLUMN IF NOT EXISTS s3_access_key    VARCHAR(255),
      ADD COLUMN IF NOT EXISTS s3_secret_key    VARCHAR(255),
      ADD COLUMN IF NOT EXISTS s3_folder_path   VARCHAR(512);
    
    UPDATE archival_setting
    SET
      sftp_server_ip   = CASE WHEN COALESCE(storage_type, 'sftp') NOT IN ('s3','minio','wasabi')
                              THEN external_server_ip ELSE sftp_server_ip END,
      sftp_username    = CASE WHEN COALESCE(storage_type, 'sftp') NOT IN ('s3','minio','wasabi')
                              THEN username ELSE sftp_username END,
      sftp_password    = CASE WHEN COALESCE(storage_type, 'sftp') NOT IN ('s3','minio','wasabi')
                              THEN password ELSE sftp_password END,
      sftp_folder_path = CASE WHEN COALESCE(storage_type, 'sftp') NOT IN ('s3','minio','wasabi')
                              THEN folder_path ELSE sftp_folder_path END,
      s3_endpoint      = CASE WHEN COALESCE(storage_type, 'sftp') IN ('s3','minio','wasabi')
                              THEN external_server_ip ELSE s3_endpoint END,
      s3_access_key    = CASE WHEN COALESCE(storage_type, 'sftp') IN ('s3','minio','wasabi')
                              THEN username ELSE s3_access_key END,
      s3_secret_key    = CASE WHEN COALESCE(storage_type, 'sftp') IN ('s3','minio','wasabi')
                              THEN password ELSE s3_secret_key END,
      s3_folder_path   = CASE WHEN COALESCE(storage_type, 'sftp') IN ('s3','minio','wasabi')
                              THEN folder_path ELSE s3_folder_path END
    WHERE sftp_server_ip IS NULL
       OR sftp_folder_path IS NULL
       OR (storage_type IN ('s3','minio','wasabi') AND s3_endpoint IS NULL);
    
    ALTER TABLE v_xml_cdr
      ADD COLUMN IF NOT EXISTS archive_storage VARCHAR(16) NULL;
    
    ALTER TABLE v_xml_cdr
      ADD COLUMN IF NOT EXISTS archive_path VARCHAR NULL;
    

    See also Archival Process Configuration for EFCX.

  5. Run ./install-efcx.sh for EFCX or run ./install-cisco.sh for Cisco UCCX and UCCE.

  6. Run the following command to ensure all the components are running. 

    # docker ps
    
  7. Once VRS is deployed with EFCX Deployment profile. Run this command on Media Server to give the permission to recording directory.

    chmod 777 -R /var/lib/freeswitch/recordings/
    
  8. In the case of Cisco Deployment Profile, navigate this URL to access the Application: https://localmachineip/#/login, whereas for EFCX Deployment Profile use the FQDN / port 444 URLs from the multi-tenant (or single-tenant) mapping steps above (steps 19–20).

  9. For HA-specific deployment, proceed following steps.

Copy the config.env file and paste it into the Recorder 2 VM and Replay Server, as most of the environment variables are the same

  1. Follow this guide for the creation of an rsync job on All VMs Recorder 1, Recorder 2, and Replay Server.

  2. Go to the replay server, add permission to install.sh script and then run ./install-replay.sh.

  3. Configure two SIP Trunks on Cisco Call Manager in HA Mode and set priorities for both Machines.

  4. Do the following steps for both recorder1 and recorder2.

  5. Open recording-solution/docker/docker-compose-cisco.yml

  6. Inside the docker-compose-cisco file, Uncomment the Consul Container.

  7. In the container_name variable, set the name as consul1 for Recorder 1 and consul2 for Recorder 2.

  8. Add your interface card. This can be found using the ifconfig or ip address command.

- CONSUL_BIND_INTERFACE=ens192   #ens192 or end32
  1. In the command section, set the name of the consul in the -node=<any-name> as shown in the code snippet below. This name must be different than the second recorder.

  2. Set the -advertise=<Local-Machine-IP> and set -retry-join=<IP-Second recorder> . Keep the other values as they are

#    command: "agent -node=consul-106 -server -ui -bind=0.0.0.0 -client=0.0.0.0 -advertise=192.168.1.106 -bootstrap-expect=2 -retry-join=192.168.1.101"
  1. Save changes and exit.

  2. Run ./install-cisco.sh

  3. Check containers on both recorders using the docker ps command

  4. Deploy the Recorder 2 in the same way.

  5. Deploy the replay server. For the replay server, just add the config.env file. and run the ./install-replay.sh command.