How to install Docker on Windows 10 without Hyper-V

Let me start by saying that it is quite hard to exactly understand the different Docker editions. Only this page is already confusing. There is a Community Edition (CE) and an Enterprise Edition (EE). But in the table there are three editions listed and none of them are named exactly the same as the names in the list. As far as I understand, the Docker Community is for free, while Docker Enterprise is the paid version.

And there is also something called Docker Engine – Community and Docker Engine – Enterprise. It seems like these are free versions, whereas the Community version for Windows 10 is also called Docker Desktop for Windows. Docker Desktop for Windows comes with an installation program and has a (basic) GUI. The version for Windows Server is Docker Engine – Enterprise and does not have a GUI nor an installation program.

Why do I start with this? Because both Docker Desktop for Windows and Docker Engine – Enterprise can be downloaded and installed for free. The Docker website does not mention any pricing for these products and the documentation makes clear how to install and does not talk about any license. I wanted to make clear that what I’m about to tell you is legal and not an infringement of any license terms.

What’s the point? Well, Docker Desktop for Windows requires Hyper-V to be enabled on your Windows 10 system, while Docker Engine – Enterprise (from now on referred to as Docker EE) does not. I was wondering if it would be possible and officially supported to install Docker EE on Windows 10. And it appears to be the case.

Why would I want that? Not because I have a problem with Hyper-V on itself. I’ve used it for many years to maintain different installations of Dynamics NAV. And even when Microsoft started to ship Dynamics NAV and Business Central as docker images, I used an Hyper-V VM with Docker installed instead of using Docker directly on my laptop. Just because Docker only supported containers in Hyper-V mode on Windows 10, which my laptop did not really like in combination with other native Hyper-V VM’s.

Since Docker supports process isolation on Windows 10 (starting with version 1809) it became time to say goodbye to my Hyper-V setup and switch to running containers directly on Windows 10. And because I didn’t need Hyper-V anymore, I also decided to get totally rid of it. That was wrong. Docker Desktop installed without complaining, but it didn’t want to start. Instead, I was presented with this screen:


And when I chose Cancel, I got this error message:

Too bad… even if you plan to not use Hyper-V based containers, you have to install Hyper-V otherwise Docker Desktop will not run after installation. I’ve heard it is because of Linux containers. They can only run inside an Hyper-V based container. And because Docker Desktop supports to switch between Windows and Linux containers, it simply expects you to have Hyper-V installed, no matter what.

Ok, but is that so bad after all? Well, maybe it is, maybe not. In my experience, Hyper-V can cause problems when combined with Docker running in process isolation mode. Especially networking seems to be quite vulnerable when Docker and Hyper-V have to work together with virtual networks.

Because Windows 10 and Windows Server share the same codebase, I was wondering if it would be possible to install Docker EE on Windows 10. Just like you install it on Windows Server. So I followed the instructions, but to no avail. I ran into another error:

Bummer…

Because I’m that kind of curious guy, I tried to find out the what this error is about. And you know what? It’s just a bug in the installation script. It’s not because Windows 10 is not supported with Docker EE. Just a bug in the script that could be solved a year ago. The script of DockerMsftProvider is available on GitHub. Make sure you are in the master branche, in case you take a look. The default development branche is already quite some commits behind master (sigh).

So, what’s the bug? There is a test on operating system, because it wants to run a different cmdlet when installing on Windows 10. It wants to test if the Windows feature Containers is installed.

And you know what? My system does not have ‘Microsoft Windows 10’ as output, but ‘Microsoft Windows 10 Pro‘. So the script fails, because it tries to run the cmdlet Get-WindowsFeature which is only available on Windows Server.

But wait… it gets worse. The suggestion in the script is that there is a difference between Windows 10 and Windows Server. Which is not true. The cmdlet Get-WindowsOptionalFeature works both on Windows Server and Windows 10! So why using the other cmdlet that is only supported on Windows Server? That’s a cmdlet you use when you want to work on a remote system. In this case that’s not what we do, so the solution here would be to just use Get-WindowsOptionalFeature (and a few lines later Enable-WindowsOptionalFeature). Without even testing on operating system, the script would be valid for both Windows 10 and Windows Server!

Of course I have made a bugfix, including some other small fixes, and created a pull request. The bad news is, there were already 5 pull request waiting, the oldest waiting for more than a year (and coincidentally for the very same bug, just a different solution). I wouldn’t be surprised if my pull request will be ignored as well.

So, what can we do to install Docker EE on Windows 10? Well, I have two options for you. Option number 1 is do a manual install, which is quite easy to do. Option number 2 is to download my version of the module DockerMsftProvider and let it install Docker for you.

Option 1: Manual install

The documentation of Docker EE contains a step-by-step instruction to use a script to install Docker EE. Follow that script and you will be safe. It can also be used to update Docker, just by downloading the latest files and overwrite the existing files.

Here is a modified version of that script. It will automatically detect the latest version for Windows version 1809, download and extract it and install it as a service.

# Install Windows feature containers
$restartNeeded = false
if (!(Get-WindowsOptionalFeature -FeatureName containers -Online).State -eq 'Enabled') {
    $restartNeeded = (Enable-WindowsOptionalFeature -FeatureName containers -Online).RestartNeeded
}

if (Get-Service docker -ErrorAction SilentlyContinue)
{
    Stop-Service docker
}

# Download the zip file.
$json = Invoke-WebRequest https://download.docker.com/components/engine/windows-server/index.json | ConvertFrom-Json
$version = $version = $json.channels.'18.09'.version
$url = $json.versions.$version.url
$zipfile = Join-Path "$env:USERPROFILE\Downloads\" $json.versions.$version.url.Split('/')[-1]
Invoke-WebRequest -UseBasicparsing -Outfile $zipfile -Uri $url

# Extract the archive.
Expand-Archive $zipfile -DestinationPath $Env:ProgramFiles -Force

# Modify PATH to persist across sessions.
$newPath = [Environment]::GetEnvironmentVariable("PATH",[EnvironmentVariableTarget]::Machine) + ";$env:ProgramFiles\docker"
$splittedPath = $newPath -split ';'
$cleanedPath = $splittedPath | Sort-Object -Unique
$newPath = $cleanedPath -join ';'
[Environment]::SetEnvironmentVariable("PATH", $newPath, [EnvironmentVariableTarget]::Machine)
$env:path = $newPath

# Register the Docker daemon as a service.
if (!(Get-Service docker -ErrorAction SilentlyContinue)) {
  dockerd --exec-opt isolation=process --register-service
}

# Start the Docker service.
if ($restartNeeded) {
    Write-Host 'A restart is needed to finish the installation' -ForegroundColor Green
    If ((Read-Host 'Do you want to restart now? [Y/N]') -eq 'Y') {
      Restart-Computer
    }
} else {
    Start-Service docker
}

Run this script, and you will have Docker EE installed on Windows 10. Make sure to save the script and use it again to update to a newer version.

Option 2: Use DockerMsftProvider

If you want to use DockerMsftProvider with my fixes, then download the module from my GitHub repository and copy it to your PowerShell modules folder. I have create a little script that downloads the two files to the PowerShell modules folder and runs the script for you.

A smal note: while testing the script again, I noticed that the path variable was not updated. I guess it’s another bug, not sure about it. So you might want to go with option 1 anyway…

$paths = $env:psmodulePath.Split(';')
$modulePath = Join-Path $paths[0] "DockerMsftProvider"
if (!(Test-Path $modulePath)) {
  New-Item -Path $modulePath -ItemType Directory
}
$outfile = Join-Path $modulePath 'DockerMsftProvider.psm1'
Invoke-WebRequest -UseBasicParsing -OutFile $outfile -Uri https://raw.githubusercontent.com/ajkauffmann/MicrosoftDockerProvider/master/DockerMsftProvider.psm1

$outfile = Join-Path $modulePath 'DockerMsftProvider.psd1'
Invoke-WebRequest -UseBasicParsing -OutFile $outfile https://raw.githubusercontent.com/ajkauffmann/MicrosoftDockerProvider/master/DockerMsftProvider.psd1

Install-Package Docker -ProviderName DockerMsftProvider -Force

And here you have Docker EE running on Windows Server 10.

Portainer

Another benefit of installing Docker EE is that Portainer works out of the box. You don’t need to do any settings, like exposing port 2375. The next two docker commands download and install Portainer for you.

docker pull portainer/portainer
docker run -d --restart always --name portainer --isolation process -h portainer -p 9000:9000 -v //./pipe/docker_engine://./pipe/docker_engine portainer/portainer

Open portainer with http://localhost:9000, provide a username and password and then click on Manage the local Docker environment. Click Connect to continue.

Then click on the local connection to manage your containers and images in a GUI.

That’s it! As you can see, it is perfectly possible to install and run Docker EE on Windows 10. For me this was really a set-and-forget installation.

Good luck!

Disclaimer: scripts are tested on my Windows 10 v1809 installation. No guarantee it will work on your installation. Scripts are provided ‘as-is’ and without any support.

Comment List
Related
Recommended