My company delivers five applications to many customers, and deployments are currently handled by copying build files to each customer's server over RDP. I want to move to Docker-based deployments so we can publish versioned images and pull them during releases, rather than manually transferring files.
I'm considering hosting a private container registry on infrastructure we control, similar to using Verdaccio for private npm packages. Each customer has their own Windows server hosted by a different provider, so we cannot depend on one cloud platform. I'd also like the registry to handle authentication and authorization so each customer can pull only the applications they are licensed to use.
Most of our customer environments are Windows, and some applications require Windows specifically. For applications that can run in containers, I'm considering using Docker with WSL on the customer servers and pulling images from the registry. Does this approach make sense? Which self-hosted registry would you recommend, and are there important Windows-container or deployment concerns I should address first?
5 Answers
Avoid making WSL a required production dependency unless you have tested it thoroughly on every customer environment. Installing extra components on customer servers can be difficult, and some organizations may not permit WSL. Use a supported Windows container runtime and automate the deployment with a pipeline or agent that can authenticate to the registry, pull the correct image, perform health checks, and roll back if necessary. The registry should be only one part of the release process.
The Windows environment is more important than the registry choice. Windows container images are tied to Windows versions and base-image builds, so an image based on Windows Server 2022 may not work with process isolation on a Server 2019 host. You may need separate image tags and a compatibility matrix for each supported host version. Windows images are also much larger than Linux images, so customer bandwidth and update time could become the real bottleneck.
Harbor is a solid choice for a serious self-hosted registry. You can create separate projects for customers or application groups, issue narrowly scoped robot credentials, and use audit logs to track image access. It also supports vulnerability scanning and replication if you need those later. For a very lightweight setup, the standard registry or Zot may be enough, while GitLab, Gitea, or Forgejo are convenient if you already use one of them for source control.
Before building and maintaining your own service, make sure self-hosting is actually cheaper and safer for your situation. Managed registries can usually be restricted to private networking, and with only a few applications the storage cost may be negligible. They also remove much of the work around patching, backups, certificates, access control, and availability. If a customer is already tied to a particular cloud, using that provider’s registry is usually the simplest option, but a neutral hosted registry can also avoid locking yourself into one cloud.
The customer servers are spread across different providers, so I prefer a provider-neutral design. I already have a deployment pipeline for another internal package and want to extend that approach instead of continuing to use RDP.
If you just need a private image store, the simplest registry implementation may be sufficient. If you need customer-level permissions, audit trails, scanning, a web interface, and long-term operational features, Harbor is a better fit. Whichever product you choose, store registry data on reliable storage, protect it with TLS, back it up, and use short-lived or tightly scoped pull credentials rather than sharing one account across every customer.

Customer-specific access is one of the main reasons I’m leaning toward self-hosting. I’d like the registry to enforce which applications each customer can pull.