Preface
In the previous chapter, we completed the deployment of Docker on a non-virtualized Windows environment. If you haven't read it yet, the author strongly recommends that you first complete the prerequisite steps: How to Use Docker with Windows Containers on Windows.
In this chapter, we will explore the challenges and scenarios that Docker faces in real-world production environments.
TL; DR
Docker on the Windows Container edition is exceptionally unique (especially within the broader Docker ecosystem), and we must build images for various infrastructure components ourselves.
The disaster struck immediately
Those who were quick to act have likely already completed the setup steps from the previous article and followed along with a simple Hello World. Up to this point, everything has looked perfectly smooth.
However, when we actually try to start a market image, Docker delivers a heavy blow.
This example attempts to start a
Docker Registryimage.

Surprisingly, Docker Hub, the largest and most commonly used public image repository, does not provide official support for a Windows-compatible Registry.
We quickly found a community-contributed registry-windows in the marketplace.
This example attempts to start the
stefanscherer/registry-windowsimage.

Sure enough, the Windows-compatible image was successfully downloaded. But when we tried to start it, Docker dealt us another fatal blow.

It simply failed to start, and mercilessly threw back a system incompatibility error at us.
Restrictions from Windows Container
In short, because Windows user mode and kernel mode are closely coupled, and Windows Containers rely heavily on specific user-mode calls into the kernel, even Microsoft cannot guarantee that unforeseen issues won't arise across different versions. Therefore, Windows Containers proactively refuse to start images that pose risks due to version mismatches.

The Real! First Image
It has to be said that when the author saw the restricted content, a momentary sense of suffocation immediately surged up, filling the entire brain. For this Docker, we were forced to manually package the image ourselves. Fortunately, nowadays the vast majority of programs are launched using various runtimes, and these runtimes, along with the programs, are highly likely to run on Windows as well. Aside from needing to manually package these images, there is nothing else particularly noteworthy.
Back to Registry
The distribution program that Docker Registry runs is written in Golang. Fortunately, in the first Image, we were able to easily get Golang running on Windows. Let's write a simple Dockerfile to package an Image.
Compile and Package Image
mkdir registry
cd registry
vim Dockerfile
Registry Dockerfile
FROM golang as build
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
RUN git clone -q https://github.com/distribution/distribution ; \
cd distribution ; \
go build -o registry.exe cmd/registry/main.go
FROM mcr.microsoft.com/windows/nanoserver:ltsc2022
COPY --from=build /go/distribution/registry.exe /registry.exe
COPY config.yml /config/config.yml
EXPOSE 5000
ENTRYPOINT ["\\registry.exe"]
CMD ["serve", "/config/config.yml"]
In this Dockerfile, we do the following:
- Use golang as our build image
- Set powershell as the command-line program to be executed subsequently
- Fetch the
distributionrepository for compilation - Prepare a release image package
- Copy the main program into the release image package
- Open port
5000 - Set the default startup program for the image
Next, we need to configure some initial options for distribution in the config.yml file
vim config.yml
For specific options, refer to CNCF Distribution - Configuring a registry
version: 0.1
log:
fields:
service: registry
storage:
cache:
blobdescriptor: inmemory
filesystem:
rootdirectory: /registry
http:
addr: :5000
headers:
X-Content-Type-Options: [nosniff]
health:
storagedriver:
enabled: true
interval: 10s
threshold: 3
validation:
disabled: true
Start building our image after saving
docker build -t registry-windows .

Done!
Testing a Real Hello World
Let's try to start it.
docker run -it registry-windows

We have successfully started Docker Registry in our Docker environment.
Let's press Ctrl + C to terminate this temporary instance and run it in the background using a more stable method.
mkdir /c/registry
docker run -d -p 5000:5000 --restart=always -v C:/registry:C:/registry --name registry registry-windows
This set of commands includes some additional settings compared to before.
| Parameter | Description |
|---|---|
-d |
Run the container as a background process |
-p 5000:5000 |
Map port 5000 inside the container to port 5000 on the host |
--restart=always |
Restart the container on any shutdown, except when the host is manually stopped |
-v C:/registry:C:/registry |
Mount the host directory C:/registry to C:/registry inside the container |
--name registry |
Assign the name registry to this instance |
We can now see it in the list of running containers using the docker ps command.

Saving Images Using Registry
Because the
Registrywe just started is not yet protected by TLS, configuring TLS certificates for the Registry is out of scope for this article. For details, please refer to Verify repository client with certificates
Configure an insecure registry for the local machine
vim /C/ProgramData/docker/config/daemon.json
Add the following content to the file
{
"insecure-registries": ["127.0.0.1:5000"]
}
Restart docker
net stop docker
net start docker
Now, we can try to commit the registry-windows package we just built to the Registry.
#为registry-windows设置一个 tag
docker tag registry-windows localhost:5000/registry:1.0.0
docker push localhost:5000/registry:1.0.0

All done!
Conclusion
Although Docker in Windows Containers has certain limitations in production environments, it is still worth a try. While this approach sacrifices Docker's out-of-the-box usability, finding images that run directly is often a matter of luck, as such compatible images are hard to come by...
Recommended repository: https://github.com/StefanScherer/dockerfiles-windows
Stefan Scherer has written Dockerfiles supporting Windows Containers for a wide range of infrastructure applications. By referring to this repository, you can quickly build images in your own Docker setup that meet your specific needs, saving a significant amount of debugging time.
Comments (0)
No comments yet. Be the first to leave one!