1. Architecture
The application and all its dependencies are compiled into a Docker image.
As soon as the container is deployed to a GCP instance, it pairs with a Salesforce org that has the Unify UI package (Installable directly through the AppExchange).
This document describes a possible configuration to manage access to the deployed instance, for example through a load balancer.
Flow Diagram
Here is the diagram describing all the inbound/outbound flows as well as the IPs and Ports requested by the application.
Security Measures
We cannot provide an example of how to implement the security layer that would fit perfectly into your architecture. However, we can provide some recommendations that are relevant to the use of the app itself.
- Protocols and Ports : All outgoing/incoming flows from the application go through the HTTPS protocol (port 443). There is no need to open another port on your VM. The DQE IPs that must be accessible are described in the preceding diagram.
- IP Filtering: The application server itself only needs to be accessible from Salesforce's servers. It is therefore recommended to set up a filtering of incoming IPs.
There is an exception to this, however, being the CustomUI web server included in the docker-compose. It must be accessible by a web browser. One solution could therefore be to allow a specific VPN to access the server. See here the list of IPs published by Salesforce. (Don't forget the Hyperforce IPs)
- Authentication protocol : Salesforce natively offers several protocols to secure requests between its servers and the DQE One server. When configuring the "DQE One Customer" Connected App in your organization, you will be able to select the "Basic Auth" authentication method and configure your application firewall accordingly.
If the VM is directly exposed to the internet, it must have a DNS entry and an associated SSL certificate that point to it.
If the VM is not directly exposed to the internet, it usually means that traffic is routed through a component such as a gateway. In this case, the DNS and the SSL certificate must be installed on that gateway, which will then forward the traffic to the internal VM.
Recommendation
In this section, we describe the list of components required to install the Unify Server DQE instance on GCP.
Note: Estimates are based on 1 million records. Depending on the volume of the databases processed, it may be necessary to increase the memory capacity of container instances to optimize processing times.
Deployment with GCP VM instances
- Server type: Unix, e.g. Ubuntu.
- Load balancer: Not required, but can be used if already available.
For more information, see the following resources:
- VM Configuration: https://cloud.google.com/compute/docs/instances
Composition and services
The docker image is a web application that exposes the services and APIs that are requested from Salesforce through the Lightning DQE Unify UI app.
For each service, we outline the attributes and their functions below.
WEB APPLICATION
A backend container that contains a microservices application. This application exposes all the APIs called to launch processes, manage processing queues, instantiate processing workers. It is dependent on the following services to function properly. This worker must be exposed on the web as described in the nginx configuration presented later in this document.
Docker Compose settings
-
image: The name of the image used by the web application. It is necessary to rename the image according to the names of the registries used. The DQE Docker images are hosted in an Azure Container Registry. The image name is constructed as follows:
<Name of the registry container>.azurecr.io/<name of the image> - container_name: Container Name
- depends_on: Name of the services that precede this service
-
domainname: The domain name used for the FQDN. Expected format:
<domain name> - environment: Service environment variables
- command: Command executed when the container is launched
Worker
A backend container that contains a microservices application. This application exposes all the APIs called to launch processes, manage processing queues, instantiate processing workers. It is dependent on the following services to function properly. This worker must be exposed on the web as described in the nginx configuration presented later in this document.
Parameters to set in Docker Compose
- image: The name of this image is the same as the web service
- container_name: The name of the container in the Docker environment
- depends_on: Name of the services that precede this service
- environment: Service environment variables
- command: Command executed when the container is launched
CustomUI
This service is a web application exposing a front used to configure deduplication rules. Like the first service, it must therefore also be exposed on the web. This service also consumes some APIs from the backend, for example to retrieve metadata from the CRM.
Registry Name: *
Image name: *
Available versions: *
Redis
This service is a key/value database used by the various departments to store internal operating keys such as Salesforce org configurations, sessions, etc.
It is possible to use official images published by Redis such as "redis:alpine", but as a security measure some cloud providers block the retrieval of public images and only allow images from private registries. To overcome this restriction, we also publish on the private registry "dqeone" a version of redis that is perfectly compatible with our applications.
Parameters
- image: Official image of redis => redis:alpine
- container_name: The name of the container in the Docker environment
-
volumes: The path of the volume to be used to back up Redis data
<name of the volume defined in this docker compose>:/data
RabbitMQ
This service is a powerful queue manager allowing the reception and scheduling of processing requests. Until a process has been assigned to a worker and completed, it will be parked in a queue. This also allows for resiliency to failures, if the server were to be restarted, it would resume the last processing in the queue where it left off.
As with the Redis service image, you have the option to use a public version (rabbitmq:3-management-alpine) or the one in the private dqeone registry.
Parameters
- image : Official image of rabbitmq => rabbitmq:3-management-alpine
- container_name : The name of the container in the Docker environment
2. Installation
Two scenarios are possible:
-
Scenario 1: The customer does not yet have a Load Balancer configured on their VM
Follow all the steps - Scenario 2: The customer already has a GCP VM with a load balancer configured
2.1. Prerequisite
Launch the dedicated server instance and connect with one of the connection options:
For more details on accessing instances through the GCP console, see the official GCP documentation.
NGINX installation
$ sudo apt update
$ sudo apt install nginxConfiguration:
- If the VM is only accessible through the load balancer, for example within a private VPC:
server {
listen 80;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8001;
}
location /api/ {
rewrite /api/(.*) /$1 break;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8000;
}- If the VM is directly exposed over HTTPS:
server {
listen 443 ssl;
server_name <e.g. exemple.com>;
ssl_certificate < location of the .crt certificate>
ssl_certificate_key < location of the private key.key>
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH: !aNULL: ! MD5;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8001;
}
Location /api/ {
rewrite /api/(.*) /$1 break;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8000;
}
}Docker installation
-
Update the existing package
$ sudo apt-get update -
Installing prerequisites for using packages over HTTPS
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common -
Adding the GPG key from the official Docker repository
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - -
Adding the Docker repository to APT sources
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable" -
Updating packages
$ sudo apt-get update -
Verification installation from Docker repository
$ apt-cache policy docker-ce -
Docker installation
$ sudo apt install docker-ce
Docker-compose installation
-
Download the desired version (Version number to change in the url)
$ sudo curl -L "https://github.com/docker/compose/releases/download/<NUMEROS_DE_VERSION>/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose -
Setting permissions
$ sudo chmod +x /usr/local/bin/docker-compose
Azure CLI installation for Azure Container Registry access
$ sudo curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash2.2. GCP Unify Server
services:
customui:
image: <imageURL>
container_name: custom-ui
logging:
driver : "json-file"
options :
max-file : 5
max-size : 50m
environment:
- PORT=8001
ports:
- 8001:8001
command: npm start
web:
image: <imageURL>
container_name: one-server
hostname: oneserver
logging:
driver : "json-file"
options :
max-file : 5
max-size : 50m
depends_on:
- redis
- rabbitmq
environment:
- SFAPIVERSION=v59.0
- PORT=8000
- REDIS_URL=redis://redis
- CLOUDAMQP_URL=amqp://guest:guest@rabbitmq/admin
- CUSTOMUI=http://customui:8001
- UNIFYSERVERURL=http://web:8000
ports:
- 8000:8000
command: bash ./entrypoint.sh
worker:
image: <imageURL>
container_name: queue-worker
logging:
driver : "json-file"
options :
max-file : 5
max-size : 50m
environment:
- SFAPIVERSION=v59.0
- WORKDIRPATH=/app/unify
- REDIS_URL=redis://redis
- CLOUDAMQP_URL=amqp://guest:guest@rabbitmq/admin
depends_on:
- web
command: python -u ./unify/queue_worker.pyc
redis:
container_name: redis
logging:
driver : "json-file"
options :
max-file : 5
max-size : 50m
image: <imageURL>
hostname: redis
volumes:
- redis_data:/data
rabbitmq:
image: <imageURL>
container_name: 'rabbitmq'
logging:
driver : "json-file"
options :
max-file : 5
max-size : 50m
environment:
- RABBITMQ_DEFAULT_PASS=guest
- RABBITMQ_DEFAULT_USER=guest
- RABBITMQ_DEFAULT_VHOST=admin
hostname: rabbitmq
depends_on:
- redis
volumes:
- rabbitmq_data:/var/lib/rabbitmq/
- rabbitmq_log:/var/log/rabbitmq/
volumes:
rabbitmq_data:
rabbitmq_log:
redis_data:3. Launcher
Although the backend server is deployed on GCP, the DQE Docker images are provided through an Azure Container Registry managed by DQE.
3.1. Connecting to the DQE Azure Container Registry
Authenticate Docker to the DQE Azure Container Registry:
$ sudo docker login **************
Username: <Login provided by DQE>
Password: <Pwd provided by DQE>3.2. Launch of docker-compose.yml
Go to the folder containing the docker-compose.yml file and run it.
$ sudo docker-compose up
Related to