Image

Local XM Cloud With Content-SDK

Learn how to stand up Sitecore XM Cloud locally with Windows Docker containers: initialize the environment, sync serialized items, configure the Content SDK rendering host, and wire Sitecore Pages for local editing—step-by-step for experienced Sitecore devs new to Docker.

Author
Robert Watson
November 06, 2025

Intro

I’ve been writing a multipart series (similar structure to the wildcard pages, custom sitemap, and server-side props posts on idksitecore.com) where each article opens with the “why”, dives into numbered build steps, drops targeted code blocks, and wraps with a “what’s next”. This entry follows the same recipe but focuses entirely on spinning up Sitecore XM Cloud locally with Docker, syncing serialized content, and wiring a Content SDK app to the local CD instance.


1. Prereqs & Mental Model

  • Windows 11/Server 2022 host with Hyper‑V, WSL2, and Docker Desktop running in Windows containers.
  • A valid license.xml on disk (C:\License\license.xml in examples).
  • Sitecore CLI 6.x installed (dotnet tool restore inside the repo handles this).
  • Access to your XM Cloud environment so you can serialize templates/content down to your machine.

2. Container Bootstrap (one‑time init)

What this does:

  1. Drops required host entries (xmcloudcm.localhost, nextjs.xmc-starter-js.localhost).
  2. Generates TLS certs via mkcert and instructs you to run setx NODE_EXTRA_CA_CERTS <path-to-rootCA.pem>.
  3. Seeds .env with image tags, SQL passwords, Auth0 config, media protection secret, JSS_EDITING_SECRET, and SITECORE_API_KEY_APP_STARTER.
  4. Ensures HOST_LICENSE_FOLDER points to the license directory.
Image

3. Full Docker Workflow (daily usage)

Under the hood the script:

  1. Verifies the Sitecore license hasn’t expired.
  2. Pulls base CM/tools images (scr.sitecore.com/...:1-ltsc2022).
  3. Builds custom images defined in docker-compose.override.yml (Node base, CM overlay, Rendering host) and persists SQL/Solr data to local-containers/docker/data.
  4. Runs docker compose up -d so the stack is: mssql, mssql-init, solr, solr-init, cm, rendering-nextjs, traefik.
  5. Waits for Traefik to expose cm-secure@docker.
  6. Restores CLI tools, performs dotnet sitecore cloud login, dotnet sitecore connect, populates Solr schemas, rebuilds indexes, pushes serialization, and imports the API key template.

NOTE: If docker compose build writes warnings to STDERR (e.g., Bake/credential helper messages), PowerShell’s $ErrorActionPreference = "Stop" may abort the script. Either patch the script to ignore those warnings or rerun the Docker commands manually (docker compose build && docker compose up -d) before re‑executing the CLI steps.

To tear everything down cleanly:

Image

4. Items You Must Serialize From Your Remote XM Cloud

When you connect to the remote XM Cloud tenant, pull everything your local environment needs to mimic production. For a reference on the serialization, I posted some examples here.

Templates & Branches

  • /sitecore/templates/Foundation/*,
  • /sitecore/templates/Feature/*,
  • /sitecore/templates/Project/*

Rendering Definitions

  • /sitecore/layout/Renderings/Feature/...,
  • /sitecore/layout/Renderings/Project/...

Placeholder Settings

  • /sitecore/layout/Placeholder Settings/...

Content Tree

  • /sitecore/content/<site> (all language versions that matter)

Media Items used locally

  • /sitecore/media library/Project/<site>

System Settings (*Most Important...otherwise you cannot connect Content SDK*)

  • /sitecore/system/Settings/Project/<site>
  • /sitecore/system/Settings/Services/API Keys

PowerShell / automation assets

  • /sitecore/system/Modules/PowerShell/...

Example pull from remote cloud:

Push the same module into local CM after containers start:

5. Keys & Environment Variables to Track

Container .env essentials

Never commit real values—check .gitignore already excludes .env.

Content SDK (Next.js) .env.local

If you’re using graph-based configuration files, also point rendering service to http://cm internally.


6. Hooking Content SDK to Local XM Cloud

  1. Ensure the rendering container mounts your app (../headapps/content-sdk-ssr:C:\app in docker-compose.override.yml).
  2. Inside headapps/content-sdk-ssr run:
  1. Confirm .env.local matches the keys above.
  2. Verify the XM Cloud CM API key exists at /sitecore/system/Settings/Services/API Keys/content-sdk-test. If not, rerun:
  1. Use Traefik’s dashboard (http://localhost:8079) to make sure rendering-secure-nextjs route is enabled.
  2. Test the app at https://nextjs.xmc-starter-js.localhost. Use docker compose logs -f rendering-nextjs for troubleshooting.
Image

7. Publishing? Not Locally.

XM Cloud local containers do not include Publishing Service and there’s no simulated CM ➜ CD promotion. Treat the environment as a developer sandbox: push serialized items, rebuild indexes, but don’t expect publish queues or workflow commands to function. For integrated testing you still push to your XM Cloud edge environment.


8. Getting Page Designer to Talk to Local CM

Sitecore Pages caches the target CM URL in browser local storage. Without overriding it, Pages keeps pointing to the hosted environment and refuses to load the local rendering host.

Steps (credit to the Fishtank article):

  1. Open Pages (https://pages.sitecorecloud.io) and log in.
  2. In DevTools → Application → Local Storage → https://pages.sitecorecloud.io, add:
  1. Reload Pages; when you open a page, it proxies requests to your local CM and the Traefik-secured rendering host.

9. Summary Checklist

  1. init.ps1 (once per machine) to generate .env, certs, hosts, and secrets.
  2. up.ps1 (each session) to pull/build/run containers + run CLI chores.
  3. Serialize templates/content/API keys from cloud (ser pull) and push into local (ser push).
  4. Keep .env keys in sync between containers and the Content SDK app.
  5. Remember: no publishing pipeline locally—serialization is your deployment story.
  6. Set Pages’ local storage override so Page Designer can target https://xmcloudcm.localhost/.

Follow that flow and anyone with Sitecore/XM Cloud experience—but minimal Docker knowledge—can clone the repo, run two scripts, sync items, and get the Content SDK rendering locally with confidence.

Made in React Bricks