Getting a WordPress instance up and running in Docker was pretty easy as it’s one of the quickstart samples on the Docker site. I only had to make a couple minor changes to match my WordPress version and create a volume mount that I could more easily access.
I used a plugin named Duplicator to move my data and files from my host to my local container. I was a little surprised to find that it goes beyond just moving your WordPress content and settings. It actually replaces the WordPress installation in it’s entirety. But it worked well and I had zero problems so I have nothing to complain about.
I did have a couple of small issues when trying to login after installing my blog locally with Duplicator. First, the login redirect was taking me to the wrong place so I had to change the site URL setting. Then I kept getting an error about my browser not supporting cookies. I found that the test cookie it was trying to set was not getting set because there was already an existing cookie that was marked as secure. Clearing all of my cookies for the site and restarting the browser seemed to get rid of it.
After I had my instance running properly, I removed some of my old plugins like WordFence and Hide Login since I won’t need them when running locally. I installed a new plugin named Simply Static to handle the static site generation. I had a couple of issues with the plugin at first, but once I sorted through them, it ended up working pretty smoothly.
First, I found that none of my pages were actually getting generated. It turned out that this was essentially because I was running in Docker. My site URL setting included port 8000 since that’s the port configured in the docker-compose file. However, the container is running the site on port 80 internally so when the plugin requests pages on port 8000, it gets nothing. I had to change the docker-compose to use port 80 for WordPress and change the site URL setting to match.
After I got a successful SSG run, I found that some of the images were broken. This was because WordPress has an annoying habit of linking images with an absolute URL. Simply Static will try to make paths root-relative for you, but your site URL needs to match the URL used in the posts. I was initially running on localhost:8000 when I installed my Duplicator package, but then changed to a custom hostname that I put in my hosts file, so I needed to clean some stuff up. I used another plugin named Search & Replace to clean up the incorrect links in my content.
After that, things mostly looked good. I just needed to make some extra change to accommodate running the site completely statically. I made some tweaks to my theme to completely remove search and comments. Basically, anything that would require a post back to the server. I also removed some extraneous stuff that WordPress adds to the head of its pages like API links and Windows Live Writer support. I also removed all of the RSS feed links except the main one that I link to in the header. A redirect (rewrite, actually) rule is needed in Netlify to support serving the feed on an extensionless URL, so I figured only having one would be better than trying to script dynamic rewrite rules for all of the categories and tags.
Getting my static site running on a free Netlify account couldn’t have been easier. I just committed the files generated by Simply Static to a git repo and pushed up to Github. Then, just stepped through Netlify’s registration which includes connecting to my Github account and selecting the repo. I changed the DNS servers for my domain to Netlify’s and it took it from there including a free Let’s Encrypt certificate for my custom domain. Did I mention that this was all free? Aside from that, all I needed to do was add a couple of config files to handle a couple of redirect rules and set up my security headers.
Now that I have all of this set up, it all works very smoothly. After I publish a new article, I just have to rerun Simply Static, commit the change to my git repo and push it up to Github. Netlify automatically sees the change and deploys it to their CDN. It’s pretty slick.
]]>When I first tried to spin up the XP0 topology in my quickstart repo, I got the following error:
ERROR: for id Container "98f3676706cf" is unhealthy. ERROR: for cm Container "98f3676706cf" is unhealthy. ERROR: Encountered errors while bringing up the project.
The container id was for mssql-init, which I found by running docker container ls -a. When I looked at the logs for that container, I didn’t see any errors or anything. I ran docker-compose up -d again and it was successful. So it seems that there wasn’t really any error, it’s just that installing all those dacpacs was taking too long.
Looking at the docker-compose.yml file I saw that there was configuration for a healthcheck and it included a start-period setting of 300s. 5 minutes is how long the mssql-init image ran before the error showed up, so I figured I could try extending that start period.
I added the setting to my docker-compose.override.yml (see line 38) and increased it until I no longer got the error when spinning up the containers from a clean state. I landed on 420s for XP0 with SXA and Headless Services. I expect that the time needed depends a fair amount on the specs of your machine. I have a fair amount of RAM on mine, but it is getting rather old. (YMMV)
There is also an environment variable named POST_DEPLOYMENT_WAIT_PERIOD that I initially thought was related to this since they were both set to 300. However, it seems that this is actually controls how long the container sleeps after the init scripts are done before the container exits. I’m not really sure what the point is or why it would need to sit around for 5 minutes after its done with its work. I decreased the value to 120 and everything seems to still work fine. ¯\_(ツ)_/¯
To be honest, I’m not thrilled with what Sitecore has provided here. It should really be easier to get a development environment up and running. I realize that the docs are trying to teach you how things work so you can customize the setup to fit your specific needs, but that should really be an optional lesson, IMHO. There should really be a quick-start that gets you going with SXA, Headless Services and the watch script without making you get into the weeds of docker build files, compose files, volume mounts, etc.
As they are, the docs start you out with spinning up a bare-bones XP0 instance. Unlike previous versions of the docs, they have you use the container deployment package rather than the docker-examples repo for this. Then they jump straight into building custom images and going back to using the docker-examples repo. After going through rather advanced topics in this custom images section, it goes back to things that are more relevant to a developer just getting started: deploying files to running containers and syncing content. I think a more natural progression would be to present the local development topics, then adding Sitecore modules and finally adding in the solution build container and other CI/CD stuff.
I’m not going to try to rewrite Sitecore’s docs for them, but I did put together a repo that I think might be a bit more helpful to developers that are trying to get started or just want to quickly spin up a local dev environment: Sitecore Docker Development Quickstart. This repo offers samples of both XP0 and XM0 topologies that include SXA and Headless Services. They also include the watch script needed to support deploying files into the running containers via volume mounts. They do not contain the solution build container, but you can do a global find-replace to uncomment those parts if you wish. Of course, you would also need to add your solution and customize the root dockerfile to suit your needs.
]]>Rather than cloning a repo, the 10.2 docs have you download a “Container Deployment Package“. The package contains several different versions of the same file that were in the repo I cloned the last time around as well as files for Kubernetes deployments. I went with the files in compose\2009\xp0. When I ran compose-init.ps1, I got an error:
A parameter cannot be found that matches parameter name 'AllowPrerelease'
Looking at the contents of the script, I could see that there were several different commands using that parameter. I figured I needed to update something, but wasn’t sure what. A quick google turned up the answer from Alex Van Wolferen. Tip: Don’t skip the part about closing and reopening your terminal, smh.
Bringing up the containers after that went pretty smoothly. I did get an error from the traefik container about “The process cannot access the file because it is being used by another process”, but that was one I have seen before, so I knew I just needed to stop IIS again since my machine had restarted since the last time I did it. I still use IIS for my main gig, so I don’t want to switch the service to a manual start.
After bringing up the new containers, I saw that I now had two versions of each container. When I used the docker-examples repo, I pulled ltsc2019 versions, while the I chose to go with the 2009 (a.k.a 20H2) from the container deployment package. I used the following commands to remove the previous versions:
docker rmi $(docker images -q scr.sitecore.com/sxp/*:*-ltsc2019) docker rmi $(docker images -q scr.sitecore.com/sxp/*/*:*-ltsc2019)
I had to use two separate commands since the wildcard doesn’t match a slash character. I’m not sure if there is a good way to do this with a single command.
I inspected my images and saw that they were using hyper-v isolation mode. Not a huge deal for me since I have 64GB of RAM, but I figured I should try to spin them up with process isolation since that’s apparently what the cool kids are doing these days. So, I ran docker-compose down, change the ISOLATION and TRAEFIK_ISOLATION variables to process in the .env file and ran docker-compose up -d again.

And here’s the error I got:
Cannot start service solr: hcsshim::CreateComputeSystem e4faa6880cbff5760d92eef0578ce1f97d001d21dde7ac48fce7aa4c9e299585: The container operating system does not match the host operating system.

I turned to google for help and found a blog post from Vincent Lui. I’m on Windows 10 21H2. According to Vincent, I could run the 20H2 versions of the Sitecore containers if I upgraded to Windows 11. Unfortunately, my current hardware isn’t compatible with Windows 11 and I don’t really want to take the time to shop and rebuild my machine just now. So it sounds like I’m SOL for the time being as far as process isolation is concerned.
]]>I already went through “Set up the environment“, but all I needed to do there was install an update for Docker Desktop. I cloned the docker-examples repo and ran init.ps1 to specify my license file and set the admin password to “b” . I ran into my first issue when I ran
docker-compose up -d and got error messages about an unhealthy container. My first few experiences with Sitecore and docker, which started before Sitecore officially supported docker were less than stable. So I figured.. “eh, clean up and try again.” Then,
“Hmmm same error.”
I opened Docker Desktop and found that the sitecore-xp0_id_1 container (identity server) had immediately exited. The logs showed an error about an invalid or expired license file. I swore I had already updated my license file this year, but I went and grabbed my 2022 license again, and reran the init script before trying to bring the containers up again. Again, I got the same license error. WTF?!
Reran the init script a couple more times with the same results and a fair amount of swearing. Finally, I thought to check the environment variables on my machine. There it was. A user level environment variable named SITECORE_LICENSE that had probably been there since I experimented with the community supported docker images a year or two ago. After deleting that environment variable and restarting my Windows Terminal, I was able to successfully bring up the containers. Yay!
While writing this post, I realized that I had been following the 10.0 docs. I just flipped over to the 10.2 version of the docs (BTW, Sitecore, if you’re reading, please make it easier to switch between product versions in the doc site. Thanks) and they don’t even mention the docker-examples repo. Instead it uses a “Sitecore Container Deployment Package”. Oh FFS… I need to go to bed…
]]>