Installing the Kajoo Plugin on Containerized Sitecore

This guide walks you through installing the Kajoo plugin on a containerized Sitecore XP or XM environment. This applies to:

  • Local Docker-based Sitecore instances
  • Production or staging environments hosted on Azure Kubernetes Service (AKS) or other container platforms

Due to Docker's architecture, you shouldn't install the .update package directly. Instead, create a Kajoo init image and incorporate it into your Content Management Docker image.


Building The Kajoo Init Asset Image

  1. Create a folder to store the files needed for image creation. This guide uses c:\SitecoreDocker\KajooImage\ as an example. Replace this path with your chosen directory throughout the instructions.

  2. Create a file named convert-update-to-image.ps1 and insert the following code:


    # Get the directory of the current script
    $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
    
    # Define the config
    $updateFilePath = Join-Path $scriptDir "Kajoo.Sitecore.Package.10.3-latest.update"
    $toolkitPath = Join-Path $scriptDir "SitecoreAzureToolkit\tools"
    $dockerInitImage = "kajoo-init"
    $dockerInitImageTag = "sc10.3"
    $outDir = $scriptDir
    $scwdpFile = Join-Path $outDir "Kajoo.Sitecore.Package.10.3.scwdp.zip"
    $scwdpExtractDir = Join-Path $outDir "scwdp-extract"
    $imagePrepDir = Join-Path $outDir "assets"
    
    # Step 1: Import the Sitecore Azure Toolkit modules
    try {
    	Import-Module (Join-Path $toolkitPath "Sitecore.Cloud.Cmdlets.dll")
        Import-Module (Join-Path $toolkitPath "Sitecore.Cloud.Cmdlets.psm1")
    } catch {
    	Write-Error "Failed to import Sitecore Azure Toolkit modules. $_"
        exit 1
    }
    
    # Step 2: Run ConvertTo-SCModuleWebDeployPackage
    try {
        ConvertTo-SCModuleWebDeployPackage -Path $updateFilePath -Destination $outDir -ErrorAction Stop
        Write-Output "Conversion to scwdp completed successfully."
    } catch {
        Write-Error "Failed to convert update package to scwdp. $_"
        exit 1
    }
    
    # Step 3: Extract SCWDP and Prep Docker Structure
    try {
        # Create directories if they don't exist
        New-Item -ItemType Directory -Path $scwdpExtractDir -Force | Out-Null
        New-Item -ItemType Directory -Path $imagePrepDir -Force | Out-Null
        New-Item -ItemType Directory -Path (Join-Path $imagePrepDir "module/db") -Force | Out-Null
        New-Item -ItemType Directory -Path (Join-Path $imagePrepDir "module/cm/content") -Force | Out-Null
    
        # Extract the SCWDP file
        Expand-Archive -Path $scwdpFile -DestinationPath $scwdpExtractDir -Force
    
        # Move DACPAC files to the destination directory
        Get-ChildItem -Path $scwdpExtractDir -Recurse -Filter *.dacpac | ForEach-Object {
            $newFileName = "Sitecore." + $_.Name
            $destinationPath = Join-Path -Path (Join-Path $imagePrepDir "module/db") -ChildPath $newFileName
            Move-Item -Path $_.FullName -Destination $destinationPath -Force
        }
    
        # Move everything in Content to module/cm/content
        Get-ChildItem -Path (Join-Path $scwdpExtractDir "Content") | ForEach-Object {
            Move-Item -Path $_.FullName -Destination (Join-Path $imagePrepDir "module/cm/content") -Force
        }
    
        # Move everything from module/cm/content/website to module/cm/content
        Get-ChildItem -Path (Join-Path $imagePrepDir "module/cm/content/Website") | ForEach-Object {
            Move-Item -Path $_.FullName -Destination (Join-Path $imagePrepDir "module/cm/content") -Force
        }
    
        # Remove the now-empty Website directory
        Remove-Item -Path (Join-Path $imagePrepDir "module/cm/content/Website") -Recurse -Force
    
    
        # Copy the web.config.xdt to the module/cm/content/Website folder
        Copy-Item -Path (Join-Path $scriptDir "web.config.xdt") -Destination (Join-Path $imagePrepDir "module/cm/content") -Force
    
        Write-Output "SCWDP extracted and Docker structure prepared successfully."
    
    } catch {
        Write-Error "Failed to prep docker image folders. $_"
        exit 1
    }
    
    # Step 4: Create the Docker Image
    try {
        $dockerInitImageFullName = "${dockerInitImage}:${dockerInitImageTag}"
    
        docker build --tag $dockerInitImageFullName . --no-cache
    
        Write-Output "Docker Init Image created successfully."
    } catch {
        Write-Error "Failed to create Docker Asset Image. $_"
        exit 1
    }

  3. Before proceeding to the next steps, note that the convert-update-to-image.ps1 file contains a configuration section. This section varies depending on your Sitecore DXP platform version. Be sure to update the configuration starting from line 4.

  4. Place the Kajoo update file obtained from the previous steps into the c:\SitecoreDocker\KajooImage\ directory.

  5. Add a Dockerfile to c:\SitecoreDocker\KajooImage with the following content:

    FROM mcr.microsoft.com/windows/nanoserver:ltsc2022 AS build
    
    COPY assets/ .
  6. Don't worry about creating an assets folder; it's automatically generated when you run the PowerShell script mentioned above. Next, download the latest Sitecore Azure Toolkit from https://developers.sitecore.com/downloads/Sitecore_Azure_Toolkit. Extract the contents and place them in a folder named SitecoreAzureToolkit. If done correctly, this folder should contain subdirectories such as tools and Copyrights.


  7. Run the PowerShell script by executing $ .\convert-update-to-image. This script will automatically build your image. In our example, we were building a 10.3 image, so our new Docker asset image is called kajoo-init:1.4-sc10.3. This may vary depending on the configuration of your PowerShell script.

    🚧

    Note

    Ensure you run the script in PowerShell 5.1. The Sitecore Azure Toolkit requires this specific version, and newer PowerShell versions will fail.


Adding the Kajoo Init Asset Image to Your Docker Environment

Before following these steps, ensure you're familiar with Docker customizations and have applied Headless Services to your Sitecore environment. For guidance on creating custom images, refer to the latest Sitecore documentation: https://doc.sitecore.com/xp/en/developers/103/developer-tools/create-custom-sitecore-images.html.

  1. Assuming you have already created custom images for CD, CM, and mssql-init for Headless Services, we'll need to make additional changes to CM and mssql-init to apply Kajoo. We'll assume your Docker build Dockerfile is located in .\docker\build\[role]. For example, the Docker file for the CM customizations would be located at .\docker\build\cm.
  2. Let's begin by making the necessary changes to the docker-compose.override.yml file.
    services:
    	mssql-init:
      	image: xm1-mssql-init:${SITECORE_VERSION}
        build:
        	context: ./docker/build/mssql-init
          args:
          	BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xm1-mssql-init:${SITECORE_VERSION}
            HEADLESS_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-headless-services-xm1-assets:22.0-ltsc2022
            KAJOO_IMAGE: kajoo-init:1.4-sc10.3
    	cm:
      	image: xm1-cm:${SITECORE_VERSION}
        build:
        	context: ./docker/build/cm
          args:
          	BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xm1-cm:${SITECORE_VERSION}
            HEADLESS_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-headless-services-xm1-assets:22.0-ltsc2022
            TOOLING_IMAGE: ${SITECORE_TOOLS_REGISTRY}sitecore-docker-tools-assets:10.3.0-1809
            KAJOO_IMAGE: kajoo-init:1.4-sc10.3
      
      cd:
      	image: xm1-cd:${SITECORE_VERSION}
        build:
        	context: ./docker/build/cd
          args:
          	BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xm1-cd:${SITECORE_VERSION}
            HEADLESS_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-headless-services-xm1-assets:22.0-ltsc2022
    Note a few key points about this file that may differ for your specific setup:
    1. I'm using an XM1 instance, but your scenario might be different.
    2. The crucial additions are KAJOO_IMAGE and TOOLING_IMAGE, which are needed to run XDT Transforms for the web.config.
      I've used a Kajoo Plugin package specifically for Sitecore 10.3, but this may vary based on your situation. This override uses multiple environment variables. While most are common in existing Docker environment configurations, there are specific registries used here. Be sure to update your environment variables with these new values, which are listed below.
    3. SITECORE_DOCKER_REGISTRY = scr.sitecore.com/sxp/
    4. SITECORE_MODULE_REGISTRY = scr.sitecore.com/sxp/modules/
    5. SITECORE_TOOLS_REGISTRY = scr.sitecore.com/tools/
  3. Now that you've configured the override docker-compose file, let's go through the steps needed for each Dockerfile. We'll start with the CM:
# escape=`

ARG BASE_IMAGE
ARG HEADLESS_IMAGE
ARG KAJOO_IMAGE
ARG TOOLING_IMAGE

FROM ${HEADLESS_IMAGE} as headless
FROM ${KAJOO_IMAGE} as kajoo
FROM ${TOOLING_IMAGE} as tooling
FROM ${BASE_IMAGE}

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

COPY --from=tooling \tools\ \tools\
COPY --from=headless C:\module\cm\content C:\inetpub\wwwroot
COPY --from=headless C:\module\tools C:\module\tools
COPY --from=kajoo C:\module\cm\content C:\inetpub\wwwroot

RUN C:\module\tools\Initialize-Content.ps1 -TargetPath C:\inetpub\wwwroot; `
  Remove-Item -Path C:\module -Recurse -Force;
  
RUN C:\tools\scripts\Invoke-XdtTransform.ps1 -Path c:\inetpub\wwwroot\Web.config -XdtPath C:\inetpub\wwwroot\Web.config.xdt; `
  Remove-Item -Path C:\inetpub\wwwroot\Web.config.xdt

There are important aspects to note in this file. On line 15, we set up the tools, which we then use to perform an XDT Transform for our web.config.xdt. This transform configures some Content Security Policy definitions in our web.config. Additionally, on line 18, we take the multi-stage build of Kajoo and move it's contents into the Sitecore website.

  1. Next, let's look at the necessary changes for the mssql-init Dockerfile:
# escape=`

ARG BASE_IMAGE
ARG HEADLESS_IMAGE
ARG KAJOO_IMAGE

FROM ${HEADLESS_IMAGE} as headless
FROM ${KAJOO_IMAGE} as kajoo
FROM ${BASE_IMAGE}

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

COPY --from=headless C:\module\db C:\resources\jss

COPY --from=kajoo c:\module\db C:\resources\kajoo

When modifying the mssql-init role, it's crucial to delete the databases in your data folder and rerun the initialization process. Failing to do so will prevent the transfer of required Kajoo Sitecore items.


What’s Next