Docker for Windows complained it was blocked by my firewall when I tried to map a host directory to a Docker container volume. In this article I’ll describe the steps I tried and what finally worked.
To be honest, it’s taken me a while to get around to playing with Docker for Windows again after my disk crashed the first time I tried. In fairness, that was unlikely to be DfW’s fault – but it was a painful experience anyway. Recently, however, I’ve been using Docker and Docker Compose on a Mac book for a client and I felt I should give it another go on my Windows laptop.
A Working Example To Start
I had no problem building and running self contained Docker images. So, with a simple
index.html in the
.\html folder, I had the following
Dockerfile using the public
nginx (web server) image:
FROM nginx COPY ./html /usr/share/nginx/html
and ran the commands:
docker build -t nginx-html-demo . docker run -d -p 8282:80 --name nginx-html-demo nginx-html-demo
Then, on browsing to http://localhost:8282 I see the following:
Nothing could be simpler! Except that, every time I modify the
index.html file I need to rebuild and restart the container.
Working with a Host Volume
So, I decided to try and map the NGINX html path inside the container directly to the
.\html directory on my Laptop so that I could try editing the
index.html file in place and see the results immediately.
For this, the plain old
nginx image is sufficient, so, ignoring the
Dockerfile, I can either run the following, lengthy Docker command:
docker run -d -p 8282:80 --name nginx-html-demo -v D:\Projects\docker\docker-nginx\html:/usr/share/nginx/html nginx
Or create a docker-compose.yml instead of the
# NGINX HTML Demo nginx: image: nginx:latest container_name: nginx-html-demo ports: - '8282:80' volumes: - D:\Projects\docker\docker-nginx\html:/usr/share/nginx/html
And run it as a daemon with the much simpler Docker Compose command:
docker-compose up -d
Either way, after a pause, a message popped up at the bottom of the screen:
Clicking ‘Share it’ results in the following output:
D:\Projects\docker\docker-nginx>docker-compose up -d Creating nginx-html-demo ... Creating nginx-html-demo ... error ERROR: for nginx-html-demo Cannot create container for service nginx: Drive sharing seems blocked by a firewall ERROR: for nginx Cannot create container for service nginx: Drive sharing seems blocked by a firewall ERROR: Encountered errors while bringing up the project.
Now, as with many of these problems, you spend hours with Google searching for some useful snippet that finally solves your problem. I did this also, and tried many solutions – but then couldn’t be certain which of the solutions were necessary. So, once I managed to get it all working, I went back and undid each of the steps individually to see which ones were actually playing their part in the fix – not least because some of them seemed worryingly insecure!
As a result, all the steps described here appear to be needed to resolve the problem – though for you, it may be that your system is setup correctly (for DfW) already.
That said, there may be one exception…
Sharing in Docker for Windows
The Windows drive you are trying to map a Volume on needs to be shared. There are two ways you might achieve this – either via Docker for Windows settings or by using the drive’s own Properties dialog.
The first method I tried was the Docker for Windows Settings dialog, 2nd tab and attempted to share the D: drive (which is where I do all my development).
I selected the D: drive and clicked Apply and, after a long wait, received the error message at the top of this article; Firewall detected. The message included a link to documentation which offered the following advice:
By default, allow connections to 10.0.75.1 port 445 (the Windows host) from 10.0.75.2 (the virtual machine). If the firewall rules appear to be open, consider reinstalling the File and Print Sharing service on the virtual network adapter.
Anyway, when I click OK, the D drive remains un-shared.
Alternatively, many articles suggest manually sharing the drive yourself. Select ‘Properties’ from the drive’s context menu in Windows Explorer and go to the Sharing tab:
Click the Advanced Sharing button and check ‘Share this folder’:
I didn’t then need to add full permissions for everyone, as some other posts mention – meaning you don’t need to click the Permissions button – but if you do, this is all I have:
You can check that it’s shared by navigating to
\\10.0.75.1\d (e.g. for the D: drive) in Windows Explorer.
Now, the remaining steps below appear to be necessary, but, when I went back and un-shared the D drive in the Docker for Windows settings, each time I clicked the ‘Share it’ button, it was re-shared. I assume, therefore, that this first step is handled by Docker itself once the other steps have been completed.
Adding the Firewall Rule
I needed to add a Firewall rule and, as I currently have Norton Security installed, I’ll show what the steps look like for that. You will need to do something similar with your own security software.
I opened up the Settings dialog (top right):
Selected Firewall (middle left):
And, on the Traffic Rules tab, clicked ‘Add’ (bottom left):
OK, you can see I’ve already added and enabled the rule – which is why all the dialogs below say ‘Modify Rule’ instead of ‘Add Rule’.
Add a rule as shown in the following dialogs:
Note: Some of the sites I found recommended opening port 139 (netbios-ssn) – as shown here – but I’ve since removed it and, so far, everything still works. Add a comment if you know a reason why it should (or shouldn’t) be opened as well.
Finally, click OK to close the dialog, then, in the Traffic Rules tab find the new rule (at the bottom of the list) and use the Move Up button to move the rule to the top and check the Active box. Click Apply then Close at the bottom right and Close on the Settings dialog.
Close the Norton Security window and you’ve done.
Make the Docker Network Private
The last step is the most obscure and requires you to make the Docker network private. The only way I’ve found to do this is to open up a Windows PowerShell window and enter the following command:
Set-NetConnectionProfile -InterfaceAlias "vEthernet (DockerNAT)" -NetworkCategory Private
I’ve also seen an approach to changing this using the Hyper-V manager – however, though articles suggest setting the network to ‘Private’, after applying the above change the network shows as Internal in Hyper-V manager.
Open Hyper-V Manager and select Virtual Switch Manager… from the list on the right:
Then select the DockerNAT network at the top left and you can see the network type:
As you can see, on my laptop, this is set to ‘Internal network’ and works fine. Just a little odd given that I’ve set it to ‘Private’ network category. I’ll have to read up on the differences…
Many articles mention the need to remove and re-add File and Printer Sharing for Microsoft Networks using the Network properties dialog. I did this once only, so I can’t confirm whether or not it made any difference.
Just in case, therefore, open the Network and Sharing Center (either from the Context menu over the network icon in the system tray or through Control Panel->Network and Internet->Network and Sharing Center. Select Change adapter settings on the left and then select the Properties from the context menu for the ‘vEthernet (DockerNAT)’ network.
In the resulting properties window, uncheck File and Printer Sharing for Microsoft Networks, close the dialog, then open it again and re-check it.
As this didn’t seem to make much difference for me I don’t know whether, for others, you might need to restart or whatever…
In summary, you need to do the following to resolve the Docker for Windows Firewall issue:
- Open up port 445 in the Firewall for the local Docker network.
- Make the local Docker network Private.
You may also need to share the relevant drive but Docker appears to manage this itself once the above steps have been taken.
Let me know if you have any other problems.
Oh, it’s probably worth mentioning here that the next problem I had was trying to use relative paths –
.\html instead of
D:\Projects\docker\docker-nginx\html. That didn’t work – but that’s for another article…