Building custom Sitecore images

Current version: 10.2

This topic explains how you layer the build output from your solution, along with other assets, onto the base Sitecore runtime images to create your own custom Sitecore images.

The following diagram shows how custom Sitecore images are created:

Sitecore images and repositories

The topic uses the Docker Examples solution to build custom Sitecore Experience Platform - Single (XP0) images to illustrate this.

This guide assumes you are able to build your solution and have a Docker solution image that contains your build artifacts, or have the build output available by traditional means.

If you have not already done so, clone the Docker Examples repository to a location on your machine. For this guide, we use the custom-images folder.

Understand the solution structure

Sitecore development with Docker introduces a new folder to a typical solution: the docker folder. The docker folder contains files and folders to support Docker development. This topic focuses on the build folder. Navigate to the custom-images\docker folder, and look at the contents of the build folder located here:

RequestResponse
build
    [service]
        Dockerfile
    ...

Each of the [service] folders:

  • Represents a container that makes up a given Sitecore topology. In this example, Sitecore Experience Platform - Single (XP0), so mssql, solr, id, cm, xconnect, and so on.

  • Contains at minimum a Dockerfile. This is a Sitecore runtime Dockerfile.

  • Is used as the Docker build context for the corresponding service in the Docker Compose file.

The Docker Examples repository includes build folders to cover services for all Sitecore topologies.

Sitecore runtime Dockerfiles

You use a Sitecore runtime Dockerfile to build your customized version of a Sitecore runtime image. We recommend you create a Dockerfile for each container that makes up your Sitecore topology.

You will create a Sitecore runtime Dockerfile for each role (container) in your Sitecore topology, even if you do not have any customization at this time. This is recommeneded because:

  • There is a dedicated layer for you to make hotfixes or future customizations in.

  • You have you own resulting image that you can name, tag, label, and store as your solution needs.

Dockerfile using solution build output

To see how you use solution build output in a Dockerfile:

  • Open the Dockerfile for the cm service (for example, C:\sitecore\docker-examples\custom-images\docker\build\cm\Dockerfile). This is an example of using the build artifacts from your solution image:

    • Initialize build stages

      Multiple build stages are initialzed:

      RequestResponse
      ARG BASE_IMAGE
      ARG SXA_IMAGE
      ARG SPE_IMAGE
      ARG TOOLING_IMAGE
      ARG SOLUTION_IMAGE
      
      FROM ${SOLUTION_IMAGE} as solution
      FROM ${TOOLING_IMAGE} as tooling
      FROM ${SPE_IMAGE} as spe
      FROM ${SXA_IMAGE} as sxa
      FROM ${BASE_IMAGE}
      

      The solution, tooling, spe, and sxa images are brought in and named to be used later on (with COPY instructions). The last part begins our custom image using the passed in Sitecore BASE_IMAGE (configured in Docker Compose).

    • Add development tools

      Development tools are copied in from the tooling image (to C:\tools). In addition to providing an ENTRYPOINT for local development, these are used later on to apply transforms:

      RequestResponse
      COPY --from=tooling \tools\ \tools\
      
    • Set working directory

      Because this uses an IIS image, most of the customizations are done within C:\inetpub\wwwroot, so this is set to the working directory:

      RequestResponse
      WORKDIR C:\inetpub\wwwroot
      
    • Add Sitecore modules

      Sitecore modules are added according to the required instructions for the cm role. Add Sitecore modules has more information. This example includes Sitecore PowerShell Extensions (SPE) and Sitecore Experience Accelerator (SXA):

      RequestResponse
      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;
      
      Note

      We recommend that you add module instructions before any solution instructions, following the Dockerfile best practice of ordering steps from least to most frequently changing to optimize caching.

    • Add files

      Next, files from the solution build image are copied in. As you recall, the output files are stored on the example solution image at \artifacts\website:

      RequestResponse
      COPY --from=solution \artifacts\website\ .\
      
    • Add transforms

      The cm service has an example of both solution and role transform files. Applying configuration transforms has more information.

      First, solution transforms are copied in (the output transforms are stored on the example solution image at \artifacts\transforms\), and then role transforms:

      RequestResponse
      COPY --from=solution \artifacts\transforms\ \transforms\solution\
      COPY .\transforms\ \transforms\role\
      
    • Apply transforms

      Finally, the solution and then role transforms are applied to the web root:

      RequestResponse
      RUN C:\tools\scripts\Invoke-XdtTransform.ps1 -Path .\ -XdtPath C:\transforms\solution\DockerExamples.Website
      RUN C:\tools\scripts\Invoke-XdtTransform.ps1 -Path .\ -XdtPath C:\transforms\role
      
    • Add items

      Depending on your Sitecore item serialization framework and strategy, your cm Dockerfile may have additional instructions here to account for these. See the the item deployment topic for details.

Empty Dockerfile

Open the Dockerfile for the id service:

RequestResponse
# escape=`

ARG BASE_IMAGE

FROM ${BASE_IMAGE}

This is an example of an empty Dockerfile. It does not have much more than the escape directive and, more importantly, the required FROM instruction, using the passed-in Sitecore BASE_IMAGE (configured in Docker Compose).

Configure in Docker Compose

You also configure build for custom Sitecore runtime images in the docker-compose.override.yml file.

Note

The docker-compose.yml file is the out-of-the-box Docker Compose file that comes with Sitecore. The docker-compose.override.yml extends the main file with overrides and extensions necessary for custom Sitecore image build and development purposes.

To configure the cm service:

  • Open the docker-compose.override.yml file at the root of the custom-images folder:

    RequestResponse
    cm:
      image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-xp0-cm:${VERSION:-latest}
      build:
        context: ./docker/build/cm
        args:
          BASE_IMAGE: ${SITECORE_DOCKER_REGISTRY}sitecore-xp0-cm:${SITECORE_VERSION}
          SPE_IMAGE: ${SITECORE_MODULE_REGISTRY}spe-assets:${SPE_VERSION}
          SXA_IMAGE: ${SITECORE_MODULE_REGISTRY}sxa-xp1-assets:${SXA_VERSION}
          TOOLING_IMAGE: ${SITECORE_TOOLS_REGISTRY}sitecore-docker-tools-assets:${TOOLS_VERSION}
          SOLUTION_IMAGE: ${REGISTRY}${COMPOSE_PROJECT_NAME}-solution:${VERSION:-latest}
      depends_on:
        - solution
      [...]
    

    Some important things to note:

    • Variable values (for example, ${SITECORE_DOCKER_REGISTRY}) can be sourced from either the environment file (.env), system environment variables on local development machines, or secrets on your build server.

    • The image name uses a -xp0-cm suffix. With the default variable values, the tagged version is docker-examples-xp0-cm:latest

    • The build context is set to ./docker/build/cm. Docker Compose uses the Sitecore runtime Dockerfile located here.

    • depends_on is set to the solution service to ensure it is built first.

The rest of the Sitecore runtime images are configured in a similar fashion. There are some additional properties configured for some of them, such as entrypoint and volumes. They are not used in the image build process so they are not described in this topic.

Adjustments for a traditional build

Even though a build Dockerfile is the preferred way to build your solution, you can still need to use more traditional ways, and use MSBuild in combination with with task runners, custom PowerShell scripts, or other build tools. This if mostly because of limitations from a legacy codebase or build process.

To adjust for a traditional build:

  1. Ensure the build output makes its way to each of the docker\build folders that require it ( cm in this example) via PowerShell or other means. This is necessary so that the build artifacts are part of the individual Dockerfile's build context.

  2. Remove the solution service and dependencies in docker-compose.override.yml.

  3. Adjust the Dockerfiles to COPY from the local build context instead of the solution image.

Build the Sitecore images

To build Sitecore images:

  1. Open a PowerShell prompt in the folder that contains the Compose files.

  2. Run the following command:

    RequestResponse
    docker-compose build
    

    This initiates the build process for the solution image and then all custom Sitecore runtime images defined. The custom Sitecore runtime images are created when complete:

    RequestResponse
    Building solution
    [...]
    Successfully built baeb10e0ed5a
    Successfully tagged docker-examples-xp0-cm:latest
    
  3. Confirm that the images were created by listing all Docker images:

    RequestResponse
    docker images docker-examples*
    
    RequestResponse
    REPOSITORY                                   TAG       IMAGE ID       CREATED          SIZE
    docker-examples-xp0-cm                       latest    59bf580e58b0   10 minutes ago   8.79GB
    docker-examples-xp0-xdbsearchworker          latest    861f52e6c9c5   11 minutes ago   7.71GB
    docker-examples-xp0-xdbautomationworker      latest    8a4c0958a121   11 minutes ago   7.69GB
    docker-examples-xp0-cortexprocessingworker   latest    d36565655830   11 minutes ago   7.68GB
    docker-examples-xp0-xconnect                 latest    88c8156afd30   11 minutes ago   8.13GB
    docker-examples-xp0-solr-init                latest    6fd0b5f9c96a   11 minutes ago   5.27GB
    docker-examples-solution                     latest    9d085019cbb7   11 minutes ago   252MB
    docker-examples-xp0-mssql                    latest    dd581e03bfd9   12 minutes ago   8.65GB
    docker-examples-id                           latest    979537c779c9   5 weeks ago      5.82GB
    

Do you have some feedback for us?

If you have suggestions for improving this article,