Sitecore 10 with Docker – Create a solution from the scratch – Create solution and enable Sitecore Serialization

  1. Sitecore 10 with Docker – Create a solution from the scratch – Setting up the first docker instance
  2. Sitecore 10 with Docker – Create a solution from the scratch – Setup Sitecore 10.3 XM setup with custom images
  3. Sitecore 10 with Docker – Create a solution from the scratch – Add Modules and enable Sitecore Serialization
  4. Sitecore 10 with Docker – Create a solution from the scratch – Create solution and enable Sitecore Serialization
  5. Sitecore 10 with Docker – Create a solution from the scratch – Add ASP.NET Rendering Host and configure SXA-JSS

Create our Solution

Now we can start creating code and a solution structure.

We will cover how we can add code to our docker environment and serialize and deserialize items.

Create the Visual Studio Solution

We will start by creating a folder structure based on Helix as followed

  • src
    • Feature
    • Foundation
    • Project

Open visual Studio and create a blank solution in your root (I named mine “MyDockerExperience”)

We create new solution folders for Projet, Foundation and Feature

Visual Studio creates by default a folder for your solution. Move the items of this folder to your root and delete the empty folder. Your root folder should look something similar like the following

Create our first project

Now we will create our first project called “MyDockerExperience.Platform”

After adding configuration folder structure it should look like following

Create a deploy folder

In our docker folder we create subfolders deploy –> platform, which will be our local deployment target for our code

Create VS publishing profile

Now we are using the previously created folder as publishing target for our platform project.

Therefore we create a new folder publishing profile in Visual Studio

In settinga we switch to Debug as it is for our dev workstation

If we publish now we are deploying to our folder.

At the moment there will be just a bin folder, as we have not patched any configuration or added any files.

Mount deployment to docker

For now we just have a folder on our filesystem where our platform is published to, but this folder and files are currently never used in our docker instances.

To be able to code for our new solution we want that our published code is deployed to the CM & CD docker instance.

For that we will start mounting our deployment folder to the CD & CM instances.

We create a new variable in our .env file and point it to our deploy folder

LOCAL_DEPLOY_PATH=.\docker\deploy

Next we mount the folder to CD & CM by adding a new volume entry in the docker-compose.override.yml

    volumes:
      - ${LOCAL_DEPLOY_PATH}\platform:C:\deploy
cm:
    image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-xm1-cm:${VERSION:-latest}
    build:
      context: ./docker/build/cm
      args:
        BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xm1-cm:${SITECORE_VERSION}
    depends_on:
      - solution
    volumes:
      - ${LOCAL_DATA_PATH}\cm:C:\inetpub\wwwroot\App_Data\logs
      - ${LOCAL_DEPLOY_PATH}\platform:C:\deploy
cd:
    image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-xm1-cd:${VERSION:-latest}
    build:
      context: ./docker/build/cd
      args:
        BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xm1-cd:${SITECORE_VERSION}
    depends_on:
      - solution
    volumes:
      - ${LOCAL_DATA_PATH}\cd:C:\inetpub\wwwroot\App_Data\logs
      - ${LOCAL_DEPLOY_PATH}\platform:C:\deploy

This means now our local path is mounted to the path C:\deploy of CD & CM.

Anyway the current code is still not part of CM & CD website, which means it is not deployed to our website.

So the next step would be to move the deployed from the mounted folder to our website.

Deploy code from mounted folder to website

Sitecore thankfully provides the Sitecore Docker Tools, which are utilities which assist Sitecore developers in initializing and running containerized Sitecore environments.

We will use first of all the sitecore-docker-tools-assets image and create an entrypoint which calls a powershell command, which monitors our deployment folder on both instances.

If you want to know more about entrypoints you can visit: https://www.bmc.com/blogs/docker-cmd-vs-entrypoint/#:~:text=Docker%20ENTRYPOINT,with%20command%20line%20arguments%20stated.

In the .env file we use following parameters

SITECORE_TOOLS_REGISTRY=scr.sitecore.com/tools/
TOOLS_VERSION=10.2-1809

In the docker-compose.override.yml we add the new TOOLING Image and the entrypoint

  cm:
      image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-xm1-cm:${VERSION:-latest}
      build:
        context: ./docker/build/cm
        args:
          BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xm1-cm:${SITECORE_VERSION}
          SPE_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-spe-assets:${SPE_VERSION}
          SXA_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-sxa-xm1-assets:${SXA_VERSION}
          HEADLESS_SERVICES_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-headless-services-xm1-assets:${HEADLESS_SERVICES_VERSION}
          MANAGEMENT_SERVICES_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-management-services-xm1-assets:${MANAGEMENT_SERVICES_VERSION}
          TOOLING_IMAGE: ${SITECORE_TOOLS_REGISTRY}sitecore-docker-tools-assets:${TOOLS_VERSION}
      volumes:
        - ${LOCAL_DEPLOY_PATH}\platform:C:\deploy
        - ${LOCAL_DATA_PATH}\cm:C:\inetpub\wwwroot\App_Data\logs
      entrypoint: powershell -Command "& C:\\tools\\entrypoints\\iis\\Development.ps1"
  cd:
      image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-xm1-cd:${VERSION:-latest}
      build:
        context: ./docker/build/cd
        args:
          BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xm1-cd:${SITECORE_VERSION}
          SXA_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-sxa-xm1-assets:${SXA_VERSION}
          HEADLESS_SERVICES_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-headless-services-xm1-assets:${HEADLESS_SERVICES_VERSION}
          TOOLING_IMAGE: ${SITECORE_TOOLS_REGISTRY}sitecore-docker-tools-assets:${TOOLS_VERSION}
      depends_on:
        - solution
      volumes:
        - ${LOCAL_DEPLOY_PATH}\platform:C:\deploy
        - ${LOCAL_DATA_PATH}\cd:C:\inetpub\wwwroot\App_Data\logs
      entrypoint: powershell -Command "& C:\\tools\\entrypoints\\iis\\Development.ps1"

Even if a lot of examples are using just one backslash for the entrypoint (e.g. C:\tools\entrypoints\iis\Development.ps1) i faced some issues with that and it worked by using double backslashes (C:\\tools\\entrypoints\\iis\\Development.ps1)

Finally in our Dockefiles for CM & CD we include the tools.

ARG TOOLING_IMAGE

FROM ${TOOLING_IMAGE} as tooling

# Copy development tools and entrypoint
COPY --from=tooling \tools\ \tools\

CD

# escape=`
ARG BASE_IMAGE
ARG SXA_IMAGE
ARG TOOLING_IMAGE
ARG HEADLESS_SERVICES_IMAGE
ARG SOLUTION_IMAGE

FROM ${SOLUTION_IMAGE} as solution
FROM ${SXA_IMAGE} as sxa
FROM ${HEADLESS_SERVICES_IMAGE} AS headless_services
FROM ${TOOLING_IMAGE} as tooling
FROM ${BASE_IMAGE}


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

# Copy development tools and entrypoint
COPY --from=tooling \tools\ \tools\

WORKDIR C:\inetpub\wwwroot

# Add SXA module
COPY --from=sxa \module\cd\content .\
COPY --from=sxa \module\tools \module\tools
RUN C:\module\tools\Initialize-Content.ps1 -TargetPath .\; `
    Remove-Item -Path C:\module -Recurse -Force;

# Copy and init the JSS / Headless Services Module
COPY --from=headless_services C:\module\cd\content C:\inetpub\wwwroot
COPY --from=headless_services C:\module\tools C:\module\tools
RUN C:\module\tools\Initialize-Content.ps1 -TargetPath C:\inetpub\wwwroot; `
    Remove-Item -Path C:\module -Recurse -Force;

CM

# escape=`

ARG BASE_IMAGE
ARG SXA_IMAGE
ARG SPE_IMAGE
ARG MANAGEMENT_SERVICES_IMAGE
ARG HEADLESS_SERVICES_IMAGE
ARG TOOLING_IMAGE
ARG SOLUTION_IMAGE

FROM ${SOLUTION_IMAGE} as solution
FROM ${SPE_IMAGE} as spe
FROM ${SXA_IMAGE} as sxa
FROM ${HEADLESS_SERVICES_IMAGE} AS headless_services
FROM ${MANAGEMENT_SERVICES_IMAGE} AS management_services
FROM ${TOOLING_IMAGE} as tooling
FROM ${BASE_IMAGE}

# Copy development tools and entrypoint
COPY --from=tooling \tools\ \tools\

WORKDIR C:\inetpub\wwwroot

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
COPY --from=spe \module\cm\content .\

COPY --from=sxa \module\cm\content .\
COPY --from=sxa \module\tools \module\tools
RUN C:\module\tools\Initialize-Content.ps1 -TargetPath .\; `
    Remove-Item -Path C:\module -Recurse -Force;

# Copy the Sitecore Management Services Module
COPY --from=management_services C:\module\cm\content C:\inetpub\wwwroot

# Copy and init the JSS / Headless Services Module
COPY --from=headless_services C:\module\cm\content C:\inetpub\wwwroot
COPY --from=headless_services C:\module\tools C:\module\tools
RUN C:\module\tools\Initialize-Content.ps1 -TargetPath C:\inetpub\wwwroot; `
    Remove-Item -Path C:\module -Recurse -Force;

Let’s have a look in the entrypoint script which we are calling when initializing the container. https://github.com/Sitecore/docker-tools/blob/main/image/src/entrypoints/iis/Development.ps1

This script is calling another script to open a file watcher handing over our mounted file path and the IIS Destination as parameter.

The called watcher script https://github.com/Sitecore/docker-tools/blob/main/image/src/scripts/Watch-Directory.ps1 identifies changes in the deploy folder and keeps the iis wwwroot folder in sync.

docker-compose down 

./clean.ps1

docker-compose build

Run docker-compose up -d

Deploy the first test page

After we successfully set up everything we want to make sure that our deployment works.

Let’s just create a simple Hello world HTML page and publish it from visual studio.

Add Sitecore Serialization to the docker environment

Previously we installed the managed services and connected via Sitecore CLI.

Now we want to serialize our first item. For the first serialization we will use the home item.

Therefore we edit the sitecore.json file in the root of our our solution folder. We add following entry

  "modules": [
    "src/*/*/*.module.json"
  ]

This is pointing to all folders 2 level under src.

Note: Remember we are setting up a solution based on helix, which means src/Layer/Projectname/*.module.json

Let’s go to the Project layer and just create a folder “Example”

In this folder we add an example.module.json file and add following content

{
    "namespace": "ExampleNamespace",
    "items": {
      "includes": [
        {
          "name": "home",
          "path": "/sitecore/content/home"
        }
      ]
    }
  }

In PowerShell we call

dotnet sitecore ser info

Result

Now we serialize items to disk by calling

 dotnet sitecore ser pull

Result

In our example folder we have now our serialized home item as yml file

Let’s open the home.yml and make some changes which we will sync with our environment (do not do this in normal development – it’s just for example reasons).

We will change the description too “Welcome to my docker experience”

In Powershell we call

dotnet sitecore ser push

By calling

dotnet sitecore ser watch

we can sync changes automatically to our file system.

In the next part we will add the ASP.NET Rendering Host and configure SXA-JSS to work with the rendering host

Leave a Comment

Your email address will not be published. Required fields are marked *