In previous blog post I shared the changes that I had to
make to deploy a Next.js solution to Sitecore MCC and Vercel. I added JSS and
SPE modules to my images and deployed them to my Azure MCC instance. In
addition to JSS and SPE I had to add Coveo for Sitecore to my images which I am
going to talk about in this blog post.
Coveo Documentation and Coveo for Sitecore Docker images
Coveo doesn’t have official support for running Coveo for
Sitecore on containers, but they have provided sufficient information on how it
can be done.
You can find high level instructions in Coveo documentation
at https://docs.coveo.com/en/lb8f0136/coveo-for-sitecore-v5/install-coveo-for-sitecore-with-sitecore-in-docker
In this documentation you’ll find a reference to a fork that
contains the Coveo for Sitecore assets as well as Coveo for Sitecore SXA
images. I specifically was interested in Coveo for Sitecore assets for Sitecore
10.2. At the time this blog post was written there was 10.2 version of Docker
images, hence I had to create my own fork with configurations for 10.2. (https://github.com/jcore/sitecore-docker-images)
The images that were created I pushed the project registry.
I can’t share the registry link here, but you can use any registry that is
available to you.
Solution Changes
Now I have a Coveo for Sitecore Docker for Sitecore 10.2 image
that I can use in my solution. Coveo provided a fork that I used in my solution
as well (https://docs.coveo.com/en/lb8f0136/coveo-for-sitecore-v5/install-coveo-for-sitecore-with-sitecore-in-docker#step-2-launch-sitecore-docker-instances-with-coveo-for-sitecore-pre-installed).
You can find at https://github.com/coveooss/sitecore-docker-examples/tree/develop/custom-images
In my solution I made the following changes:
.env
# Coveo env section
COVEO_INIT_IMAGE=[You registry url where the Docker
image you created in previous step was deployed. Ex. [registry url]/custom-coveo5011101-assets:10.2.0-20220328.1]
COVEO_VERSION=[Coveo version without dots. Ex. 5011101]
COVEO_API_KEY=[API Key created in Sitecore (see Coveo
API Keys section of this blog post.)]
COVEO_SEARCH_API_KEY=[API Key created in Sitecore (see
Coveo API Keys section of this blog post.)]
COVEO_ORG_ID=[Coveo organization ID that you can find
in Coveo Cloud Portal]
COVEO_USER=[Sitecore user that Coveo for Sitecore
module will use.]
COVEO_PASSWORD=[Sitecore Coveo account password]
COVEO_FARMNAME=[Coveo farm name]
Adding COVEO_API_KEY in Coveo
Create an API key in Coveo Cloud portal. Copy the guid and
add it to your .env file for the COVEO_API_KEY variable.
Go back to the Coveo Cloud portal and double click on the
key that you just added and make sure that Privileges are set to be as follows:
If privileges are not set correctly, the activation script
that runs during the application pipeline execution will fail.
Adding COVEO_SEARCH_API_KEY in Coveo
Add the second key to Coveo API keys for the search. Add the
guid for the key to your .env file.
Go back to the Coveo Cloud portal and double click on the
key that you just added and make sure that Privileges are set to be as follows:
Copying COVEO_ORG_ID from Coveo
Go to Organization section in the navigation on the left and
click on Settings. In the modal window select Organization tab and click on
Information menu item. Here you’ll find the Organization ID value. Copy and
paste it into your .env file.
Other variables
Create a user in Sitecore for Coveo to use the same way you
would do it when you install Coveo for Sitecore module in a non-container
instance.
Coveo farm name can be anything or even empty for local
environment.
Updating docker-compose.yml
coveo-init:
isolation: ${ISOLATION}
image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-coveo-init:${COVEO_VERSION}-${SITECORE_VERSION}
environment:
COVEO_API_KEY: ${COVEO_API_KEY}
COVEO_SEARCH_API_KEY: ${COVEO_SEARCH_API_KEY}
COVEO_ORG_ID: ${COVEO_ORG_ID}
COVEO_USER: sitecore\${COVEO_USER}
COVEO_PASSWORD: ${COVEO_PASSWORD}
COVEO_HOST: http://cm
SITECORE_ADMIN_USER: sitecore\${SITECORE_ADMIN_USER}
SITECORE_ADMIN_PASSWORD: ${SITECORE_ADMIN_PASSWORD}
COVEO_FARMNAME: ${COVEO_FARMNAME}
depends_on:
cm:
condition: service_healthy
mssql:
condition: service_healthy
Updating
docker-compose.override.yml
coveo-init:
image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-coveo-init:${VERSION:-latest}
build:
context: ./docker/build/coveo-init
args:
BASE_IMAGE: mcr.microsoft.com/powershell:nanoserver-1809
Adding coveo-init image
Take the code for this image from Coveo fork. I didn’t make
any changes to these files.
CM, CD, and MSSQL-Init image changes
In docker-compose.override.yml add the following line to cm,
cd and mssql-init images under args:
COVEO_ASSET: ${COVEO_INIT_IMAGE}
Like so:
mssql-init:
image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-xp1-mssql-init:${VERSION:-latest}
build:
context: ./docker/build/mssql-init
args:
BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xp1-mssql-init:${SITECORE_VERSION}
SPE_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-spe-assets:${SPE_VERSION}
HEADLESS_SERVICES_IMAGE: ${HEADLESS_SERVICES_IMAGE}
COVEO_ASSET: ${COVEO_INIT_IMAGE} # No buildable 10.2 version tags yet.
Now try running “docker-compose build” command. If it
succeeds, you can run docker-compose up -d to make sure the Coveo for
Sitecore module is showing up in CM and is also activated.
If everything works as expected, you can try deploying the
new images to MCC.
Deploying to MCC
Push new cm, cd, mssql-init and coveo-init
images to your Azure Registry.
In application repository for MCC the following changes
had to be made:
1.
Update the image references for cm, cd,
and mssql-init in .
2.
Add a new image reference called coveoinit.
3.
Under roles/sitecore-xp/templates add a
new file called coveo-init.yaml with the following content:
. ---
5. apiVersion: batch/v1
6. kind: Job
7. metadata:
8. name: coveo-init
9. spec:
10. template:
11. spec:
12. nodeSelector:
13.
kubernetes.io/os: windows
14. imagePullSecrets:
15.
- name: sitecore-docker-registry
16. containers:
17. - name: coveo-init
18.
image: "{{
docker_images.sitecore.coveoinit }}"
19.
env:
20.
- name: COVEO_API_KEY
21.
valueFrom:
22.
secretKeyRef:
23.
name: sitecore-coveo-api-key
24.
key: sitecore-coveo-api-key.txt
25.
- name: COVEO_SEARCH_API_KEY
26.
valueFrom:
27.
secretKeyRef:
28.
name: sitecore-coveo-search-api-key
29.
key: sitecore-coveo-search-api-key.txt
30.
- name: COVEO_ORG_ID
31.
valueFrom:
32.
secretKeyRef:
33.
name: sitecore-coveo-org-id
34.
key: sitecore-coveo-org-id.txt
35.
- name: COVEO_USER
36.
valueFrom:
37.
secretKeyRef:
38.
name: sitecore-coveo-user
39.
key: sitecore-coveo-user.txt
40.
- name: COVEO_PASSWORD
41.
valueFrom:
42.
secretKeyRef:
43.
name: sitecore-coveo-password
44.
key: sitecore-coveo-password.txt
45.
- name: COVEO_HOST
46.
valueFrom:
47.
secretKeyRef:
48.
key: cm
49.
name: sitecore-hostname
50.
- name: COVEO_FARMNAME
51.
valueFrom:
52.
secretKeyRef:
53.
key: sitecore-coveo-farmname.txt
54.
name: sitecore-coveo-farmname
55.
- name: SITECORE_ADMIN_USER
56.
valueFrom:
57.
secretKeyRef:
58.
name: sitecore-admin-domain-username
59.
key: sitecore-admin-domain-username.txt
60.
- name: SITECORE_ADMIN_PASSWORD
61.
valueFrom:
62.
secretKeyRef:
63.
name: sitecore-admin
64.
key: sitecore-adminpassword.txt
65. restartPolicy: Never
66. backoffLimit: 5
67.
4. Add secret keys for all new variable in
the file above.
5. In the same folder open secrets.yaml
file and add the following section right before “parameters”.
- data:
- key: sitecore-coveo-api-key.txt
objectName: sitecore-coveo-api-key
secretName: sitecore-coveo-api-key
type: Opaque
- data:
- key: sitecore-coveo-search-api-key.txt
objectName: sitecore-coveo-search-api-key
secretName: sitecore-coveo-search-api-key
type: Opaque
- data:
- key: sitecore-coveo-org-id.txt
objectName: sitecore-coveo-org-id
secretName: sitecore-coveo-org-id
type: Opaque
- data:
- key: sitecore-coveo-user.txt
objectName: sitecore-coveo-user
secretName: sitecore-coveo-user
type: Opaque
- data:
- key: sitecore-coveo-password.txt
objectName: sitecore-coveo-password
secretName: sitecore-coveo-password
type: Opaque
- data:
- key: sitecore-coveo-farmname.txt
objectName: sitecore-coveo-farmname
secretName: sitecore-coveo-farmname
type: Opaque
- data:
- key: sitecore-admin-domain-username.txt
objectName: sitecore-admin-domain-username
secretName: sitecore-admin-domain-username
type: Opaque
At the end of objects array in parameters section of
the same file add the following section at the very end of the string:
- |
objectName: sitecore-coveo-api-key
objectType: secret
- |
objectName: sitecore-coveo-search-api-key
objectType: secret
- |
objectName: sitecore-coveo-org-id
objectType: secret
- |
objectName: sitecore-coveo-user
objectType: secret
- |
objectName: sitecore-coveo-password
objectType: secret
- |
objectName: sitecore-coveo-farmname
objectType: secret
- |
objectName: sitecore-admin-domain-username
objectType: secret
6. At the end of main.yaml file in roles/sitecore-xp/tasks
folder add the following:
- name: Execute post-init
containers
include_tasks: post-init.yaml
when: hadr_resources.isExecuteInitContainer|bool==true
7. In the same folder add a new post-init.yaml
file with the following content:
---
- name: 'Wait - cm running'
k8s_info:
kind: Pod
label_selectors:
- app = cm
namespace: "{{ solution_id
}}"
wait: true
wait_sleep: 30
wait_timeout: 180
wait_condition:
type: Ready
status: "True"
- name: Execute coveo-init job
k8s:
apply: true
namespace: "{{ solution_id
}}"
state: present
definition: "{{
lookup('template', 'coveo-init.yaml') }}"
- name: 'Wait - coveo-init job'
k8s_info:
kind: Job
name: coveo-init
namespace: "{{ solution_id
}}"
register: coveo_init_result
until: (coveo_init_result.resources[0].status.conditions[0].type
| default('')) == 'Complete'
retries: 30
delay: 30
- name: Get all coveo-init
completed pods
k8s_info:
kind: Pod
namespace: "{{ solution_id
}}"
label_selectors:
- job-name = coveo-init
no_log: true
register: coveo_pod_list
- name: Remove coveo-init job's
pods
k8s:
kind: Pod
name: "{{
item.metadata.name }}"
namespace: "{{ solution_id
}}"
state: absent
no_log: true
with_items: "{{
coveo_pod_list.resources }}"
- name: Remove coveo-init job
k8s:
kind: Job
name: coveo-init
namespace: "{{ solution_id
}}"
state: absent
no_log: true
This is the Ansible instructions for
running of coveo-init job. The job will spin off a new pod as well. To
make sure that Coveo activation happens every time you do a deployment, the Ansible
script deletes the pod and the job.
Check
in the changes, create a pull request and merge the branch with your changes to
the master branch. That should trigger the application pipeline execution.
If
everything runs without error, you see Coveo for Sitecore module installed in
your CM instance, and it is enabled, congratulations! If you are having issues,
you can remove the deletion of the job and the pod temporarily to check if you
see errors there. Often secret keys are not configured correctly, that would
cause the job to fail.