I am using docker-compose to expose a docker service in my windows 10 machine.
Also, using a function in golang to check whether the service is completely up or not:
package main
import (
"fmt"
"net"
)
func main() {
err := ping(9800)
fmt.Println(err)
}
func ping(port uint16) (err error) {
fmt.Println("checking port:", port)
conn, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", port))
if err != nil {
return
}
conn.Close()
return
}
Docker and Go versions used now are:
C:\>docker version
Client: Docker Engine - Community
Version: 19.03.2
API version: 1.40
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:26:49 2019
OS/Arch: windows/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.2
API version: 1.40 (minimum version 1.12)
Go version: go1.12.8
Git commit: 6a30dfc
Built: Thu Aug 29 05:32:21 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.2.6
GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc:
Version: 1.0.0-rc8
GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f
docker-init:
Version: 0.18.0
GitCommit: fec3683
C:\>go version
go version go1.13.1 windows/amd64
The container is up and the service is exposed via hostPort 50014:
C:\>docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
48eeb27f5ddc d.reg.io/adata "/usr/local/bin/adat…" 7 seconds ago Up 4seconds 0.0.0.0:50014->50014/tcp desktop_adata_1
When running the go script to bind to the port 50014, it returns error:
C:\>go run ping.go
checking port: 50014
listen tcp 127.0.0.1:50014: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
This happens only after the update to docker-for-windows version 19.03.2.
Can someone help me to solve this issue?
UPDATE:
There is a question: What is Administered port exclusions in windows 10?
It is true that the port 50014 comes in administered port exclusions range.
I thought removing the port from that exclusion list or using any other port will work. But I used host ports 80, 8080, 50014 and 9800 one by one to expose the service and tried to bind them. But every time it failed.
Port 80 and 8080 are non-excluded ports. The container is up and the service is listening on the port. But gives error while trying to bind using the go function:
checking port: 80
listen tcp 127.0.0.1:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
Port 50014 is in administered port exclusion range. The container is up and the service is listening on the port. It also gives the same error while trying to bind:
checking port: 80
listen tcp 127.0.0.1:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
Port 9800 is in the normal port exclusion range. The difference is, this time the container will not be up. Docker cannot use that host port to expose a service. It will give an error when running docker-compose up -d
:
Creating desktop_adata_1 ... error
ERROR: for desktop_adata_1 Cannot start service adata: driver failed programming external connectivity on endpoint desktop_adata_1 (1a5978c5fbf35cb08fce14c8d5192756b3de8a77bd815f490e3e8ce542abaeaa): Error starting userland proxy: listen tcp 0.0.0.0:9800: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
That means, in my case, the reason for the error would be the net.Listen() fails to bind to a port that is used for a docker container service.
After docker update, net.Listen()
was not able to ping to a port that is already used to expose a Docker container service.
As a workaround, I used net.Dial()
instead of net.Listen()
in the go code.
It works as expected.