How to install Docker on Windows 10 without Hyper-V

4 Mar

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. πŸ˜‰

21 thoughts on “How to install Docker on Windows 10 without Hyper-V

  1. I almost did the same,

    Invoke-WebRequest -UseBasicParsing -OutFile docker-18.09.0.zip https://download.docker.com/components/engine/windows-server/18.09/docker-18.09.0.zip
    Expand-Archive docker-18.09.0.zip -DestinationPath $Env:ProgramFiles -Force
    $null = Install-Package Docker -ProviderName DockerMsftProvider -Force
    dockerd –register-service
    Start-Service docker

    – If I tried to install Docker EE using powershell it got an SHA error and it did not install.
    – I had to use the Install-Package Docker line several times before it worked.

    I tried your script and it worked like a charm first time. Very Well done!

    One ot the benefits of EE over the Desktop Engine is that when you shutdown Windows 10 1809+ it makes a shutdown way faster.

    • Thanks Palle!

      I noticed you used Install-Package together with download / expand archive. That’s not needed. It is just a matter of download / expand archive / register as service. Nothing more. πŸ˜‰

      Yes, it is way faster, both startup and shutdown!

  2. I ran into the same problem when installing Docker Desktop on my Windows 10 Pro laptop after that I had removed Hyper-V from it.

    Will remove Hyper-V again and try the script to install Docker-EE in coming weeks.

    Thanks for sharing this Arend-Jan!

  3. On my Windows 10 Enterprise N Version 1809 (OS Build 17763.316) laptop, the container creation/startup of Portainer fails. This seems to be due to the fact that the Portainer image is not yet build for 1809. When I instead use the image from chocolateyfest/portainer:latest, everything works perfect.

    The question that now arises however is whether there is a difference between the container handling on Windows 10 Professional Version 1809 and Windows 10 Enterprise N 1809? Or could it be that you somehow still have Hyper-V (artifacts) installed which allows Portainer to run in hyper-v mode instead of process mode?

    Anyone attempting this setup should also be aware that many images on Docker Hub are “not yet” available as 1809 images, this includes for example SQL Server Developer Edition. You may need to build some images yourself using the nanoserver:1809 image. Fortunately that is not true for NAV/BC images as Freddy has already updated all images to enable running on 1809 OS-es. (ltsc-2019 tag) πŸ™‚

    I hope this info helps some others running into the same issues as I did.

    • Thanks for the heads up, Ivo.
      It worked at the moment of posting. But two days ago, the portainer image was updated to version 1.20.2. And that latest version doesn’t run anymore.
      If you pull the previous image portainer/portainer:1.20.1 it will work. Or use the image you suggest. πŸ˜‰

      Opened an issue about this: https://github.com/portainer/portainer/issues/2758

      • Thanks Arend-Jan that solved the issue. Better to stick to the official maintainers images than pulling them somewhere else as I suggested.

  4. Pingback: Business Central Docker on Windows 10 - Gunnar's Blog - Dynamics 365 Business Central/NAV User Group - Dynamics User Group

  5. Hi,

    I tried your way to get Portainer running in Windows 10 (1809) and oit worked πŸ™‚
    But now I am only allowed to run “Windows Images” and “Linux Images” are nt any longer allowed to run….so bad πŸ™

    Or is there a way to get Linux-Images runable in this environment?

    Thanks
    Chrostoph

    • That will not work. Linux images can’t run in process isolation on a Windows machine, you need Hyper-V isolation for that. So your only option is to install Hyper-V and Docker Desktop. The setup I described is for Windows containers only.

  6. The docker engine installed successfully but I am missing the whale icon from the system tray. Can we enable that for docker engine version

    • No, that is not possible. Docker engine runs as a service, it does not include a desktop icon. If you want to have the whale icon, then you should install Docker Desktop.

  7. But why to deal with Docker EE in the first place?

    You can just use Docker CE with Hyper-V disabled – no problem at all – and you don’t even need Docker Desktop, just binaries: docker and dockerd. Link: https://master.dockerproject.org/windows/x86_64/docker.zip

    First step is to create create config file (like daemon.json) and add “exec-opts”: [“isolation=process”] and pass it to dockerd with –config-file flag or just use –isolation-process flag with docker run, like “docker run –isolation=process -itd mcr.microsoft.com/windows/nanoserver:1809 cmd”. It works, just works.

    Of course you must at first “Start-Process dockerd (…) -Verb RunAs” or run it as a service after ‘dockerd –register-service’, Start-Service docker.

    Anyway, even if you have installed Docker Desktop, which as we know forces us to enable Hyper-V, we can just disable virutalization support in Bios (like Intel Virtual Technology) and Hyper-V Windows Features, and we still be able to work with Docker service and run Windows Containers in process isolation mode, passing the correct flag. If we try to run a container with isolation=hyperv, we will receive an error: “The virtual machine could not be started because a required feature is not installed”.

    Funny observation: if virtualization is enabled in Bios, but Hyper-V Windows Features disabled, we can still run Windows Containers in hyperv isolation mode. Because Windows Containers doesn’t need Hyper-V VM! If you run the container in isolation mode, Hyper-V manager returns nothing. As far as I know the Windows Features are only needed for Linux Containers, as they need MobyLinuxVM created in Hyper-V.

    • Remember: just bypass the GUI, like disable/remove ‘Docker for Windows.exe’ from Windows startup. Because Desktop can have annoying notifications, I work only in command line / PowerShell.

      • I guess I’m doing the same, just download a zip file with the binaries. Someone told me the engine of CE and EE is basically the same, but I can’t tell that from the binaries. Anyway, it doesn’t really matter which one you download, right?

        So, if I get you right, you suggest to:
        * Install Docker Desktop
        * Disable Docker Desktop to run at Windows login –> this basically disables Docker
        * Register dockerd as a service –> no need for Docker Desktop at all

        I think that might work as well.

        Just one comment: don’t know if it is still the case, but if I remember correctly, Docker CE has a different pipe endpoint. I think it is pipe/docker_engine_windows instead of pipe/docker_engine (as it is on Windows Server). In my experience, I couldn’t get portainer to work with the pipe/docker_engine_windows endpoint. I had to expose port 2375 for that. But the pipe/docker_engine endpoint works fine with portainer.

        And because the DockerMsftProvider is supposed to support both Windows Server and Windows 10, I assumed it would be a good idea to fix that or to come up with an alternative to achieve the same.

        • I have little experience with EE. If you have Docker Desktop installed, it has already Docker Engine service registered.

          Disable:
          * Docker Desktop at startup
          * Docker Desktop Service (com.docker.service)

          Leave:
          * Docker Engine service (docker)

          As for pipe name, In my case it’s docker_engine. I have Docker Engine – Community ver. 18.09.2.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.