Docker was built for Sitecore Commerce XC 9.3

Akshay Sura - Partner

20 Apr 2020

Share on social media

In this blog post, we shall continue our Docker journey to hopefully reach a state where we could get Docker to help us with the Sitecore Commerce development.

I truly believe Docker was built for Sitecore Commerce. If you have been part of Sitecore Commerce projects, you would know that it takes quite a few installations on vm’s or the local machine to get up and running. You should also know that from time to time, you simply want to just wipe out your machine and restart the process again. No amount of checkpoints would save you on your hyper-v’s 😉

Docker manages this very easily. I could simply wipe out my whole environment and relaunch it within minutes.

Before we go on, I want to thank all the community and sitecore contributors for working on the Sitecore Docker repo - https://github.com/Sitecore/docker-images.

In my previous blog post Dockerify your Sitecore 9.3 XP development environment - SSL, CM and Identity we talked about setting up SSL and getting our CM and Identity servers up and running.

Identity Server

I missed a few instructions on the Identify server configuration in my previous blog post. Since we need to revisit it for the Sitecore Commerce setup, might as well get both done with.

You need to add to your data folder (data\identity\wwwroot\Config\production), the Sitecore.IdentityServer.Host.xml config. Here you would specify the CertificateThumbprint (Generate any random one), PasswordRecoveryUrl (Your Identity server url), AllowedCorsOrigins (Your CM url for now) and the ClientSecret (Randomly generated key).

<?xml version="1.0" encoding="utf-8"?><Settings> <Sitecore> <IdentityServer> <CertificateThumbprint>9F03BC8B4612D53B4E818972E7981A221CD61FSC</CertificateThumbprint> <CertificateStoreLocation>LocalMachine</CertificateStoreLocation> <CertificateStoreName>My</CertificateStoreName> <SitecoreMembershipOptions> <ConnectionString>Data Source=sql;Initial Catalog=Sitecore.Core;User ID=sa;Password=8Tombs-Given-Clock#-arming-Alva-debut-Spine-monica-Normal-Ted-About1-chard-Easily-granddad-5Context!</ConnectionString> </SitecoreMembershipOptions> <AccountOptions> <PasswordRecoveryUrl>https://identity.bemyfriend.local/sitecore/login?rc=1</PasswordRecoveryUrl> </AccountOptions> <Clients> <DefaultClient> <AllowedCorsOrigins> <AllowedCorsOriginsGroup1>https://cm.bemyfriend.local</AllowedCorsOriginsGroup1> </AllowedCorsOrigins> </DefaultClient> <PasswordClient> <ClientSecrets> <ClientSecret1>wHycAnTYOUBmYfr1EndPGGt2pUNhkxDRq0TCBoR4PjHTCYMW0rCrIDKH42qET4iDMYihXmDtVE2wckcb3AGx265ErSWMYdInV0O0</ClientSecret1> </ClientSecrets> </PasswordClient> </Clients> </IdentityServer> </Sitecore>

You also need to add Sitecore.Commerce.IdentityServer.Host.xml to your data folder (data\identity\wwwroot\Config\production). Here you would specify the same CertificateThumbprint as the one from Sitecore.IdentityServer.Host.xml file, PasswordRecoveryUrl (Your Identity server url), AllowedCorsOrigins (Your CM url for now) and the ClientSecret same as the one from Sitecore.IdentityServer.Host.xml file.

<?xml version="1.0" encoding="utf-8"?><Settings> <Sitecore> <IdentityServer> <CertificateThumbprint>9F03BC8B4612D53B4E818972E7981A221CD61FSC</CertificateThumbprint> <CertificateStoreLocation>LocalMachine</CertificateStoreLocation> <CertificateStoreName>My</CertificateStoreName> <SitecoreMembershipOptions> <ConnectionString>Data Source=sql;Initial Catalog=Sitecore.Core;User ID=sa;Password=8Tombs-Given-Clock#-arming-Alva-debut-Spine-monica-Normal-Ted-About1-chard-Easily-granddad-5Context!</ConnectionString> </SitecoreMembershipOptions> <AccountOptions> <PasswordRecoveryUrl>https://identity.bemyfriend.local/sitecore/login?rc=1</PasswordRecoveryUrl> </AccountOptions> <Clients> <DefaultClient> <AllowedCorsOrigins> <AllowedCorsOriginsGroup1>https://cm.bemyfriend.local</AllowedCorsOriginsGroup1> </AllowedCorsOrigins> </DefaultClient> <PasswordClient> <ClientSecrets> <ClientSecret1>wHycAnTYOUBmYfr1EndPGGt2pUNhkxDRq0TCBoR4PjHTCYMW0rCrIDKH42qET4iDMYihXmDtVE2wckcb3AGx265ErSWMYdInV0O0</ClientSecret1> </ClientSecrets> </PasswordClient> </Clients> </IdentityServer> </Sitecore>

Commerce Authoring, Minions, Ops and Shops

To get the four commerce roles on SSL, we did something similar to the CM. We have a specific PowerShell script in the startup that added the SSL bindings and called the C:\tools\entrypoints\sitecore-xc-engine\Development.ps1 script. The C:\tools\entrypoints\sitecore-xc-engine\Development.ps1 is specific to the commerce roles.

[CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$EntryPointScriptPath = "C:\tools\entrypoints\sitecore-xc-engine\Development.ps1" ) Write-Host "Running startup.ps1" Import-Module WebAdministration $website = "Default Web Site" Write-Host "Checking if $($website) has any existing HTTPS bindings" $hostHeaders = "${env:HOST_HEADER}".Split(";", [System.StringSplitOptions]::RemoveEmptyEntries) function Set-HttpBinding { param( [string]$SiteName, [string]$HostHeader ) if ($null -eq (Get-WebBinding -Name $siteName | Where-Object { $_.BindingInformation -eq "*:80:$($hostHeader)" })) { Write-Host "Adding a new HTTP binding for $($siteName)" $binding = New-WebBinding -Name $siteName -Protocol http -IPAddress * -Port 80 -HostHeader $hostHeader } else { Write-Host "HTTP binding for $($siteName) already exists" } if ($null -eq (Get-WebBinding -Name $siteName | Where-Object { $_.BindingInformation -eq "*:443:$($hostHeader)" })) { Write-Host "Adding a new HTTPS binding for $($siteName)" $securePassword = (Get-Content -Path C:\startup\cert.password.txt) | ConvertTo-SecureString -AsPlainText -Force $cert = Import-PfxCertificate -Password $securePassword -CertStoreLocation Cert:\LocalMachine\root -FilePath C:\startup\cert.pfx $thumbprint = $cert.Thumbprint $binding = New-WebBinding -Name $siteName -Protocol https -IPAddress * -Port 443 -HostHeader $hostHeader $binding = Get-WebBinding -Name $siteName -Protocol https $binding.AddSslCertificate($thumbprint, "root") } else { Write-Host "HTTPS binding for $($siteName) already exists" } } foreach($hostheader in $hostHeaders) { Set-HttpBinding -SiteName $website -HostHeader $hostheader } Write-Host "Running $($EntryPointScriptPath)" & $EntryPointScriptPath

The Docker compose file for the commerce roles is shown below:

commerce-authoring: image: ${REGISTRY}sitecore-xc-engine-authoring:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} entrypoint: PowerShell.exe -NoLogo -NoProfile -File C:\\startup\\startup-commerce.ps1 mem_limit: ${MEM_LIMIT_COMMERCE:-1GB} volumes: - .\data\commerce-authoring\logs:C:\inetpub\wwwroot\wwwroot\logs - .\data\commerce-authoring\wwwroot:C:\src - .\startup:C:\startup ports: - "44005:80" - "44006:443" networks: default: aliases: - commerce-authoring.bemyfriend.local environment: HOST_HEADER: commerce-authoring.bemyfriend.local depends_on: - sql - solr isolation: ${ISOLATION} restart: always container_name: commerce-authoring.bemyfriend.local commerce-minions: image: ${REGISTRY}sitecore-xc-engine-minions:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} entrypoint: PowerShell.exe -NoLogo -NoProfile -File C:\\startup\\startup-commerce.ps1 mem_limit: ${MEM_LIMIT_COMMERCE:-1GB} volumes: - .\data\commerce-minions\logs:C:\inetpub\wwwroot\wwwroot\logs - .\data\commerce-minions\wwwroot:C:\src - .\startup:C:\startup ports: - "44010:80" - "44011:443" networks: default: aliases: - commerce-minions.bemyfriend.local environment: HOST_HEADER: commerce-minions.bemyfriend.local depends_on: - sql - solr isolation: ${ISOLATION} container_name: commerce-minions.bemyfriend.local commerce-ops: image: ${REGISTRY}sitecore-xc-engine-ops:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} entrypoint: PowerShell.exe -NoLogo -NoProfile -File C:\\startup\\startup-commerce.ps1 mem_limit: ${MEM_LIMIT_COMMERCE:-1GB} volumes: - .\data\commerce-ops\logs:C:\inetpub\wwwroot\wwwroot\logs - .\data\commerce-ops\wwwroot:C:\src - .\startup:C:\startup ports: - "44015:80" - "44016:443" networks: default: aliases: - commerce-ops.bemyfriend.local environment: HOST_HEADER: commerce-ops.bemyfriend.local depends_on: - sql - solr isolation: ${ISOLATION} container_name: commerce-ops.bemyfriend.local commerce-shops: image: ${REGISTRY}sitecore-xc-engine-shops:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} entrypoint: PowerShell.exe -NoLogo -NoProfile -File C:\\startup\\startup-commerce.ps1 #entrypoint: PowerShell.exe -Command "& C:\\tools\\entrypoints\\sitecore-xc-engine\\Development.ps1" mem_limit: ${MEM_LIMIT_COMMERCE:-1GB} volumes: - .\data\commerce-shops\logs:C:\inetpub\wwwroot\wwwroot\logs - .\data\commerce-shops\wwwroot:C:\src - .\startup:C:\startup ports: - "44020:80" - "44021:443" networks: default: aliases: - commerce-shops.bemyfriend.local environment: HOST_HEADER: commerce-shops.bemyfriend.local depends_on: - sql - solr isolation: ${ISOLATION} container_name: commerce-shops.bemyfriend.local

In your commerce solution, modify the config.json in the wwwroot folder and modify the SitecoreIdentityServerUrl and the AllowedOrigins attributes with appropriate values.

"SitecoreIdentityServerUrl": "https://identity.bemyfriend.local", "AllowedOrigins": [ "https://bizfx.bemyfriend.local", "https://cm.bemyfriend.local" ],

BizFx

Next in line is the BizFx server configuration.

Official Definition: The Sitecore Commerce Business Tools (BizFX) role provides a single point of access to an interface allowing business users and commerce administrators to perform activities related to merchandising, pricing, promotions, orders and customers management, but also more advanced administrator tasks.

Since we already configured the CM, all four commerce roles and the Identity roles, its super easy to configure the BizFx role.

You need to add to your data folder (data\bizfx\wwwroot\assets), the config.json file. Here you would specify the EngineUri (Your Sitecore Commerce Authoring role url), IdentityServerUri (Your Identity server url) and the BizFxUri (Your BizFx url). You can also modify the other config items if necessary.

{ "EnvironmentName": "HabitatAuthoring", "EngineUri": "https://commerce-authoring.bemyfriend.local", "IdentityServerUri": "https://identity.bemyfriend.local", "BizFxUri": "https://bizfx.bemyfriend.local", "Language": "en", "Currency": "USD", "ShopName": "CommerceEngineDefaultStorefront", "LanguageCookieName": "selectedLanguage", "EnvironmentCookieName": "selectedEnvironment", "AutoCompleteTimeout_ms": 300 } The following is the Docker compose definition for the BizFx role:

bizfx: image: ${REGISTRY}sitecore-xc-bizfx:${SITECORE_VERSION}-windowsservercore-${WINDOWSSERVERCORE_VERSION} entrypoint: PowerShell.exe -NoLogo -NoProfile -File C:\\startup\\startup.ps1 mem_limit: ${MEM_LIMIT_SERVICES:-1GB} volumes: - ${LICENSE_PATH}:C:\license - .\data\bizfx\logs:C:\inetpub\wwwroot\logs - .\startup:C:\startup - .\data\bizfx\wwwroot:C:\src ports: - "4200:80" - "4201:443" networks: default: aliases: - bizfx.bemyfriend.local environment: HOST_HEADER: bizfx.bemyfriend.local depends_on: - commerce-authoring - identity isolation: ${ISOLATION} restart: always container_name: bizfx.bemyfriend.local

Credit where its due

  • Kamruz Jaman - Thanks for all the help.

If you have any questions, please get in touch with me. @akshaysura13 on Twitter or on Slack.

Sign up to our newsletter


Tags:


Share on social media

Akshay Sura

Akshay is a nine-time Sitecore MVP and a two-time Kontent.ai. In addition to his work as a solution architect, Akshay is also one of the founders of SUGCON North America 2015, SUGCON India 2018 & 2019, Unofficial Sitecore Training, and Sitecore Slack.

Akshay founded and continues to run the Sitecore Hackathon. As one of the founding partners of Konabos Consulting, Akshay will continue to work with clients to lead projects and mentor their existing teams.


Subscribe to newsletter