As I mentioned in my recent blog posts, Docker was built for Sitecore Commerce. The script I use for commerce deploys locally to Docker is similar to what I used to use for a local install when using Sitecore Commerce 9.2 and 9.1.
I modified the script a tiny bit to work with my Docker instances.
Please go through our previous blog posts on Docker for Sitecore Commerce: Dockerify your Sitecore 9.3 XP development environment - SSL, CM and Identity
Docker was built for Sitecore Commerce XC 9.3
Once your commerce solution is up and running you have to perform the following tasks to push your .NET Core app:
- Build your
Sitecore.Commerce.Engine.exe
(console app with IIS bindings) - Build all the project references of Sitecore.Commerce.Engine project (DLL’s)
- Gather the build output
- While making a copy for
Authoring
,Minions
,Ops
andShops
, modify theAppSettings
in thesrc\Sitecore.Commerce.Engine\wwwroot\config.json
file. We need to modify theSiteTitle
andEnvironmentName
- Remove Kestrel related attributes
SslPort
,SslPfxPath
andSslPfxPassword
- Push the appropriate temp folder to the appropriate Docker data folder for Authoring, Minions, Ops and Shops,
- If
Bootstrap
flag is passed in, get the Token from the Identity server and Bootstrap the Commerce engine on the Ops role
NOTE: Be careful when you build the solution using dotnet publish as opposed to the Sitecore.Commerce.Engine project, we ran in to an odd issue and documented it in a blog post: Sitecore Commerce Build & Deployment Error - Could not load file or assembly System.Runtime.CompilerServices.Unsafe Version=4.0.4.1 and System.IO.Compression Version=4.2.0.0
Here are the AppSettings from the Docker\data\commerce-minions\wwwroot\wwwroot\config.json
:
"AppSettings": {
"SiteTitle": "CommerceMinions_FRIEND",
"BootStrapFile": "Global",
"DeploymentId": "Deployment01",
"EnvironmentName": "BeMyFriendMinions",
"EncryptionProtectionType": "Machine",
"EncryptionCertificateHash": "Enter a valid certificate thumbprint for a PXF file. X-509 not supported yet",
"EncryptionSID": "Enter a valid SID for a domain registered user",
"EncryptionKeyStorageLocation": "c:\\Encryption-Keys\\",
"SitecoreIdentityServerUrl": "https://identity.BeMyFriend.local",
"AllowedOrigins": [
"https://bizfx.BeMyFriend.local",
"http://cd.BeMyFriend.local",
"https://cm.BeMyFriend.local",
"https://localhost:4200"
],
"AntiForgeryEnabled": false,
"CommerceServicesHostPostfix": "",
"UseHttpsInKestrel": "false"
}
Here the copy of my script which I use multiple times daily and it works on my machine ;)
Param(
[string]$identityServerHost = "identity.BeMyFriend.local",
[switch]$Bootstrap,
[switch]$SkipPublish,
[string]$dockerDataRoot = "C:\code\BeMyFriend\Docker\data",
[string[]] $engines = @("Authoring", "Minions", "Ops", "Shops"),
[string]$CommerceOps = "commerce-ops.BeMyFriend.local",
[string]$adminUser = "admin",
[string]$adminPassword = "b",
[string]$solutionFolder = "C:\code\BeMyFriend\Commerce",
[string]$publishFolder = (Join-Path $solutionFolder "publishcode"),
[string]$engineProjectPath = (Join-Path $solutionFolder "src\Sitecore.Commerce.Engine\Sitecore.Commerce.Engine.csproj")
)
Function Start-CommerceEngineCompile ( [string] $basePublishPath = $(Join-Path $publishFolder "engine") ) {
if (Test-Path $publishFolder) {
Remove-Item -Path $publishFolder -Recurse -Force
}
Write-Host ("Compiling and Publishing Engine to {0}" -f $basePublishPath) -ForegroundColor Green
dotnet publish $engineProjectPath -o $basePublishPath
}
Function Start-CommerceEnginePrepare ( [string] $basePublishPath = $(Join-Path $publishFolder "engine") ) {
foreach ($engine in $engines) {
Write-Host ("Customizing configuration values for {0}" -f $engine) -ForegroundColor Green
$engineFullName = ("commerce-{0}" -f $engine)
$engineFullName = $engineFullName.ToLower()
$siteTitle = $("Commerce" + $engine + "_FRIEND")
$environmentName = ("BeMyFriend{0}" -f $engine)
$enginePath = Join-Path $publishFolder $engineFullName
Copy-Item $basePublishPath $enginePath -Recurse -Force
$pathToJson = $(Join-Path -Path $enginePath -ChildPath "wwwroot\config.json")
$config = Get-Content $pathToJson -Raw | ConvertFrom-Json
$appSettings = $config.AppSettings
$appSettings.EnvironmentName = $environmentName
$appSettings.SiteTitle = $siteTitle
$appSettings = $appSettings| Select-Object * -ExcludeProperty SslPort, SslPfxPath, SslPfxPassword
$config.AppSettings = $appSettings
$config | ConvertTo-Json -Depth 10 -Compress | set-content $pathToJson
}
}
Function Publish-CommerceEngine {
Write-Host ("Deploying Commerce Engine") -ForegroundColor Green
foreach ($engine in $engines) {
$engineFullName = ("commerce-{0}" -f $engine)
$engineFullName = $engineFullName.ToLower()
$enginePath = ("{0}\{1}\*" -f $publishFolder,$engineFullName)
$engineWebRoot = ("{0}\{1}\wwwroot" -f $dockerDataRoot, $engineFullName)
Write-Host ("Copying to {0}" -f $engineWebRoot) -ForegroundColor Green
if (Test-Path $engineWebRoot) {
$deleteFiles = Join-Path $engineWebRoot "\*"
Remove-Item -Path $deleteFiles -Recurse -Force -Exclude *.gitkeep
}
Copy-Item -Path "$enginePath" -Destination $engineWebRoot -Container -Recurse -Force
}
}
Function Get-IdServerToken {
$UrlIdentityServerGetToken = ("https://{0}/connect/token" -f $identityServerHost)
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Type", 'application/x-www-form-urlencoded')
$headers.Add("Accept", 'application/json')
$body = @{
password = "$adminPassword"
grant_type = 'password'
username = ("sitecore\{0}" -f $adminUser)
client_id = 'postman-api'
scope = 'openid EngineAPI postman_api'
}
Write-Host "Getting Identity Token From Sitecore.IdentityServer" -ForegroundColor Green
$response = Invoke-RestMethod $UrlIdentityServerGetToken -Method Post -Body $body -Headers $headers
$sitecoreIdToken = "Bearer {0}" -f $response.access_token
$global:sitecoreIdToken = $sitecoreIdToken
Write-Host $global:sitecoreIdToken
}
Function BootStrapCommerceServices {
$UrlCommerceShopsServicesBootstrap = ("https://{0}/commerceops/Bootstrap()" -f $CommerceOps)
Write-Host "BootStrapping Commerce Services: $($urlCommerceShopsServicesBootstrap)" -ForegroundColor Green
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", $global:sitecoreIdToken)
Invoke-RestMethod $UrlCommerceShopsServicesBootstrap -TimeoutSec 1200 -Method PUT -Headers $headers
Write-Host "Commerce Services BootStrapping completed" -ForegroundColor Green
}
if (!($SkipPublish)) {
Start-CommerceEngineCompile
Start-CommerceEnginePrepare
Publish-CommerceEngine
}
if ($Bootstrap) {
Get-IdServerToken
}
if ($Bootstrap) {
BootStrapCommerceServices
}
If you have any questions, please get in touch with me. @akshaysura13 on twitter or on Slack.