Docker was built for Sitecore Commerce XC 9.3

Docker was built for Sitecore Commerce XC 9.3

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.

Docker Sitecore Commerce

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></Settings>

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></Settings>

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

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

KONABOS