Deploying items
This topic explains Sitecore item package and deployment automation strategies on Docker. There are different ways to do this, depending on the item serialization tool you use.
Sitecore CLI and Sitecore Content Serialization
The Sitecore CLI is optimized for scripted interaction with a remote Sitecore instance. It can be used to package items during your continuous integration process, and to install those packages during your deployment and delivery process. Automating item deployment into a Sitecore environment with the Sitecore CLI is no different when using containers.
The Sitecore CLI documentation has more details, and the Sitecore module reference has information about installing the required Sitecore Management Services module in your CM container image.
Sitecore TDS
Sitecore TDS has a number of built-in tools that facilitate item packaging and deployment. The general approach is to use these tools to create item packages during your solution build, and then add them to the Content Management (CM) image when building your Sitecore runtime images.
The Helix.Examples repository on GitHub has a complete example.
Sitecore TDS Project Configuration
This example takes advantage of two Sitecore TDS features: Build Output and WebDeploy Packages. These are settings configured on the TDS project property pages:
-
Build Output Path - Located on the Build page, you set this for the
Release
build configuration. Specify a path shared by all TDS projects. In our example, this is set to..\..\TdsGeneratedPackages\Release\
. -
Build WebDeploy package - Located on the WebDeploy Package page, select this for the
Release
build configuration. Specify a Package Name, and select Item only Package for Code and Item Packaging Options.
The following assumes you have configured your TDS projects accordingly.
Configure in solution build
Sitecore TDS requires licensing environment variables for Docker or cloud builds:
-
In your solution build Dockerfile, declare
ARG
s for these at the start of your code compilation and build stage (builder
in the examples):RequestResponseARG TDS_Owner ARG TDS_Key
The location within the Dockerfile is important due to
ARG
scope. If you instead declare these in a previous build stage, the values are empty when used in thebuilder
stage. Also note thatARG
is used instead ofENV
because these are only used for building the image.These values are populated for the
solution
service in thedocker-compose.override.yml
file, for example:RequestResponsesolution: image: ${REGISTRY}${COMPOSE_PROJECT_NAME}-solution:${VERSION:-latest} build: context: . args: BASE_IMAGE: ${SOLUTION_BASE_IMAGE} BUILD_IMAGE: ${SOLUTION_BUILD_IMAGE} TDS_Owner: ${TDS_OWNER} TDS_Key: ${TDS_KEY} scale: 0
You can have the
TDS_OWNER
andTDS_KEY
values in the environment file (.env), but usually you specify them as system environment variables on local development machines and as secrets on your build server (for security purposes). -
In the solution build Dockerfile, you can simplify the
msbuild
instruction, and instead rely on the build output configured in your TDS projects:RequestResponseRUN msbuild /p:Configuration=Release
The build output lands at the location specified in the TDS project (the Build Output Path), relative to the
builder
'sWORKDIR
. In the example, this means build output is:-
\build\TdsGeneratedPackages\Release
(files) -
\build\TdsGeneratedPackages\WebDeploy_Release
(WDP item packages)
You copy these in from the
builder
stage to the final image with the following structure:-
\artifacts\website
-
\artifacts\packages
-
\artifacts\transforms
-
-
You can adjust the final instructions to:
RequestResponseWORKDIR C:\artifacts COPY --from=builder \build\TdsGeneratedPackages\Release .\website\ COPY --from=builder \build\TdsGeneratedPackages\WebDeploy_Release .\packages\ COPY --from=builder C:\out\transforms .\transforms\
Add to Sitecore CM runtime image
When you have packaged and included items with the solution
image, you can add them to the Content Management (CM) image when you build your Sitecore runtime images.
At the end of the Dockerfile for your cm service, add instructions to deploy your item packages. TDS has 2 options for handling this:
-
Option 1: Deploy on container create
This allows Sitecore TDS to install item packages on site startup. It uses a built-in feature of TDS. However, you must be aware that this happens every time a container is created using this image:
RequestResponseCOPY --from=solution \artifacts\packages\ \temp\ RUN Get-ChildItem -Path 'C:\\temp\\*.wdp.zip' | % { Expand-Archive -Path $_.FullName -DestinationPath 'C:\\temp' -Force; }; ` Move-Item -Path 'C:\\temp\\Content\\Website\\Bin\*' -Destination .\bin -Force; ` Move-Item -Path 'C:\\temp\\Content\\Website\\temp\*' -Destination .\temp -Force; ` Remove-Item -Path 'C:\\temp' -Recurse -Force; ` # Ensure TDS has permissions to delete items after install cmd /C icacls .\temp\WebDeployItems /grant 'IIS AppPool\DefaultAppPool:(OI)(CI)M';
-
Option 2: Deploy on-demand
Use the
Deploy-TdsWdpPackages.ps1
script from thetooling
image. Copy it in along with your packages:RequestResponseCOPY --from=tooling \tools\scripts\Deploy-TdsWdpPackages.ps1 \install\Deploy-TdsWdpPackages.ps1 COPY --from=solution \artifacts\packages\ \install\packages\
You can then invoke
Deploy-TdsWdpPackages.ps1
on the container on-demand with the following script:RequestResponsedocker exec <container> powershell -command "C:\install\Deploy-TdsWdpPackages.ps1"
Unicorn
Unicorn is a third-party open source tool which is not supported by Sitecore Support. These instructions are provided as guidance only, for the convenience of Unicorn users.
Unlike the other serialization tools described here, Unicorn does not have a built-in packaging capability, and it runs in-process with the Sitecore platform. Therefore, the serialized items in your Unicorn configuration need to be present in the filesystem of the Content Management instance weher you want to sync them. When you use Docker this is easy because you can copy the items during your container build. Unicorn also provides a PowerShell module to trigger item synchronization. This is convenient for automating item deployment when using containers.
The following steps assume you are already using Docker to build your solution and create a custom Sitecore images. Refer to the Helix.Examples repository on GitHub for a complete example.
Add serialized items to your solution artifacts
When you use Unicorn, you typically place the serialized items within your Sitecore solution source, and organize them in a structure that is defined by your Unicorn configuration, potentially following Sitecore Helix practices. You can copy all these serialized items during your solution build, but retaining their directory structure is important. Robocopy is one easy option for accomplishing this:
# Copy serialized items, retaining directory structure
RUN Invoke-Expression 'robocopy C:\build\src C:\out\items /s /ndl /njh /njs *.yml'
# ... later in your artifacts build stage
WORKDIR C:\artifacts
COPY --from=builder c:\out\items .\items\
Build items and deployment scripts into your CM image
Now that you have items as build artifacts in your solution image, copy them into your CM image, just as you have done previously with your msbuild
output. Additionally, place the files needed for Unicorn remoting in the CM image, so that you can later run a scripted sync from a CM container:
-
A
unicorn
folder in your CM build context must contain the files needed for Unicorn remote scripting:-
MicroCHAP.dll
-
Unicorn.psm1
-
A custom
sync.ps1
-
-
The
sync.ps1
script in this case must contain a standard invocation ofSync-Unicorn
, and use an environment variable to populate the Unicorn shared secret:RequestResponse$ScriptPath = Split-Path $MyInvocation.MyCommand.Path Import-Module $ScriptPath\Unicorn.psm1 Sync-Unicorn -ControlPanelUrl 'http://localhost/unicorn.aspx' -SharedSecret $env:UNICORN_SHARED_SECRET
-
In your CM Dockerfile, copy in this folder and the serialized items artifact, and set an environment variable that you can use later for configuring Unicorn:
RequestResponse# Set the default location for serialized items # This value will be used in our Unicorn configuration ENV ITEM_SYNC_LOCATION c:\items # Copy serialized items and Unicorn sync script COPY --from=solution \artifacts\items\ \items\ COPY .\unicorn \unicorn\
Configure Unicorn and your Docker environment
The base filesystem path used for Unicorn sync is typically set in Sitecore configuration using an sc.variable
called sourceFolder
:
-
Populate this value from the environment variable defined above in our
Dockerfile
.RequestResponse<sc.variable name="sourceFolder" value="$(env:ITEM_SYNC_LOCATION)" />
-
Populate the Unicorn shared secret from an environment variable as well, allowing you to use the same environment variable as you did in
sync.ps1
previously:RequestResponse<authenticationProvider type="Unicorn.ControlPanel.Security.ChapAuthenticationProvider, Unicorn"> <SharedSecret>$(env:UNICORN_SHARED_SECRET)</SharedSecret> </authenticationProvider>
-
Define this environment variable in your
docker-compose.override.yml
and.env
:RequestResponsecm: [...] environment: UNICORN_SHARED_SECRET: ${UNICORN_SHARED_SECRET}
RequestResponseUNICORN_SHARED_SECRET=your-secret-here
Run a sync
At this point, you have everything you need to trigger an item sync with Unicorn:
-
Serialized items on the filesystem of your CM container
-
Unicorn configured to use this path as its item source
-
The Unicorn shared secret configured via an environment variable
-
A PowerShell script to trigger the sync
When you want to deploy the items, whether manually or within your delivery pipeline, use docker exec
, or the equivalent within your production container orchestrator:
docker exec <container> powershell -command "c:\unicorn\sync.ps1"