I have a golang
application which starts a TCP
server on port 8080. Every thing works fine when I run the app native.
However when I run it as a container, I am unable to even telnet
to the port from within the container itself.
docker ps
9bb08785b728 dp_local "/bin/dragonpit-linux" 8 seconds ago Up 7 seconds 8080-8081/tcp youthful_villani
docker exec -it youthful_villani sh
/ # telnet localhost 8080
telnet: can't connect to remote host (127.0.0.1): Connection refused
Note: used 0.0.0.0
as well as 127.0.0.1
in place of localhost
TCP Server starting code
var err error
var lc net.ListenConfig
th.listener, err = lc.Listen(ctx, "tcp", "0.0.0.0:8080")
if err != nil {
return err
}
clog.Info(ctx, "tcp protocol listening", "listenAddr", th.addr)
I hard-coded the address to see whats the issue.
My Dockerfile
FROM golang:1.18.0 as builder
RUN mkdir -p /build/
ADD . /build
WORKDIR /build
RUN CGO_ENABLED=0 GOOS=linux go build -o tcp_server
FROM alpine:latest
EXPOSE 8080 8081
RUN mkdir -p /server/config
ADD config /server/config/
ENV SMC_PATH /
COPY --from=builder /build/tcp_server /bin/
RUN apk update
RUN apk add busybox-extras
ENTRYPOINT ["/bin/tcp_server"]
Output of docker-inspect
"NetworkSettings": {
"Bridge": "",
"SandboxID": "a70f476a8a7376b1e5a935b67170145f2222e059c5b2a1a63da50519a491babf",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"8080/tcp": null,
"8081/tcp": null
},
"SandboxKey": "/var/run/docker/netns/a70f476a8a73",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "7b6b9d0d5f83b8136919ac0f765167f6d380a8d836f460a0243bedeb3489a013",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "16563fdda1d5059bb6e2800455f2e87ac8d02e040386eae595a215692e849d76",
"EndpointID": "7b6b9d0d5f83b8136919ac0f765167f6d380a8d836f460a0243bedeb3489a013",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
Docker running command and starting logs
docker run dp_local
25T14:59:46.367075600Z","caller":"build/main.go:24","msg":"Starting listening","listenAddr":"0.0.0.0:8080"
Edit:
I just printed out the Addr().String()
of TCP Listener
, I got this
{"level":"info","ts":"2022-04-25T15:44:28.952095700Z","caller":"server/tcp.go:65","msg":"[::]:8080"}
2
Answers
Answering my question here. It was actually a TCP parameter which was set incorrectly and caused issues. The culprit was MTU. For reference: https://www.baeldung.com/cs/tcp-max-packet-size#:~:text=The%20maximum%20size%20of%20a,size%20should%20never%20exceed%20MTU.
Two Assumptions based on your question
In that case you need to bind the Docker container ports to ports on an interface on the local machine. Let’s use localhost. You docker run command should look like
This will bind container ports 8080 to 8080 and 8081 to 8081 on localhost of local machine.
Read more here