I came across this error the other day when I was working on windows with Docker
Cannot start service db: failed to create endpoint dotnet-album-viewer_db_1 on network nat: failed during hnsCallRawResponse: hnsCall failed in Win32: The process cannot access the file because it is being used by another process. (0x20)
To say it’s misleading would be charitable – I was confused by this confusing message. Found the answer but it was a bit scattered over the internet so I thought I would bring it together.
The error
Consider this docker-compose.yml file
version: '3.2' services: db: image: dockersamples/tidb:nanoserver-sac2016 ports: - "3306:4000" app: image: dockersamples/dotnet-album-viewer build: context: . dockerfile: docker/app/Dockerfile ports: - "80:80" environment: - "Data:Provider=MySQL" - "Data:ConnectionString=Server=db;Port=4000;Database=AlbumViewer;User=root;SslMode=None" depends_on: - db networks: default: external: name: nat
We are running a database container (db) and an application container (app). When we run
docker-compose up -d
to bring up the containers we get the error
Cannot start service db: failed to create endpoint dotnet-album-viewer_db_1 on network nat: failed during hnsCallRawResponse: hnsCall failed in Win32: The process cannot access the file because it is being used by another process. (0x20)
It makes it seem like the container is locked in some way, perhaps two instances running concurrently. That’s not the issue.
The cause
The problem is that we are running the containers on ports that have been taken by other processes. So, in my case it is both the database container and the application server that are at fault
Database container
db: image: dockersamples/tidb:nanoserver-sac2016 ports: - "3306:4000"
The database container connects on port 4000 in the network internal to the containers. The second port 3306 is what is exposed to the host machine. It’s port 3306 that is already taken by another process. To find which application is running on that port use netstat and PowerShell i.e.
netstat -aon | findstr 3306
which gives
MySql is on port 3306 hence I can’t run a container on that port and I get the weird ‘process cannot access file’ error. That does make sense as the image dockersamples/tidb:nanoserver-sac2016 is a MySQL compatible database – so it’s on the same port.
Application container
The application server is also targeting an in-use port
app: image: dockersamples/dotnet-album-viewer build: context: . dockerfile: docker/app/Dockerfile ports: - "80:80"
The application container will use port 80 internally and also port 80 externally. I don’t need to go the trouble of running netstat. I know I’ve got a webserver (IIS) on that machine which has a default website running on port 80. I should have spotted that straight away and been a bit less baffled.
The resolution
I can either kill the processes that are taking that port or change the external port that the docker containers are going to use. I don’t really want to kill MySQL or IIS so I need 2 new ports.
I tend to use ports above 49200 as they are dynamic ports and are less likely to be in use (though I tend to use them up myself, so I still get clashes). Specifically
Well-known ports range from 0 through 1023.
Registered ports are 1024 to 49151.
Dynamic ports (also called private ports) are 49152 to 65535.
Once you’ve identified a port you can check if it’s in use by using netstat again
netstat -aon | findstr 49301
And see if you get a result. So, the final resolution is
version: '3.2' services: db: image: dockersamples/tidb:nanoserver-sac2016 ports: - "49301:4000" app: image: dockersamples/dotnet-album-viewer build: context: . dockerfile: docker/app/Dockerfile ports: - "49250:80" environment: - "Data:Provider=MySQL" - "Data:ConnectionString=Server=db;Port=4000;Database=AlbumViewer;User=root;SslMode=None" depends_on: - db networks: default: external: name: nat
So db and app external ports are now in the dynamic range and when I run
docker-compose up -d
the error is gone, and my containers and the application come up. Lovely.
Useful links
The examples in this post come from here https://github.com/docker/labs/blob/master/windows/windows-containers/WindowsContainers.md
Useful post on how to check if your ports are in use. Further detail and explanation to what I’ve posted here.
List of well known ports https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers. Searching for port 3306 on Wikipedia would have shown me that it’s in use by MySQL. I guess a lot of people would have just known this. I didn’t.
Stack overflow answer as a reminder on which port in the docker-compose file is the external port and which one is the one used internally by docker. Spoiler alert: the first one is the externally exposed port and the second one is use by the applications running inside of the docker containers. It’s the first port that is causing us the problems.