SoFunction
Updated on 2025-03-03

Solve the problem that the port cannot be accessed when docker deploys golang http service

You need to use docker to containerize golang's httpserver. In this process, I encountered a low-level problem. The port cannot be accessed during golang http service. Here is a record of the process of solving this problem.

1. Background

1.1 Problem Description

Problem description: After the docker image starts, it cannot be accessed through curl:

[root@hecs-205828 ~]# curl -XGET http://127.0.0.1:8360/hello
curl: (56) Recv failure: Connection reset by peer

1.2 webserver code

go file:

package main

import (
   "fmt"
   "net/http"
   "os"
   "strings"
)

func main() {
   ("/hello", handler_hello)
   ("/healthz", handler_healthz)
   ("127.0.0.1:8360", nil)
}

func handler_healthz(w , r *) {
   ()
   ([]byte("OK"))
}

func handler_hello(w , r *) {
   ("method = ", )
   ("URL = ", )
   ("RemoteAddr = ", )
   ("IP = ", (, ":")[0])
   ("header = ", )
   ("body = ", )
   (, "Connected successfully")

   for name, values := range  {
      for _, value := range values {
         (name, value)
         _, exits := ()[name]
         if exits {
            ().Add(name, value)
         } else {
            ().Set(name, value)
         }
      }
   }
   VERSION := ("VERSION")
   ("VERSION is :", VERSION)
   ().Set("VERSION", VERSION)
   ()
   ([]byte("hello http server"))
}

document

Dockerfile file:

FROM golang:1.17 AS build

WORKDIR /web-server/

COPY . .
ENV CGO_ENABLED=0
ENV GO111MODULE=on
ENV GOPROXY=,direct
RUN GOOS=linux go build -installsuffix cgo -o web-server 

FROM busybox
COPY --from=build /web-server/web-server /web-server/web-server
EXPOSE 8360
ENV ENV local
WORKDIR /web-server/
ENTRYPOINT ["/web-server/web-server"]

2. Problem analysis

I found that curl cannot access the services in the docker container, and the telnet result is as follows:

[root@hecs-205828 ~]# telnet 127.0.0.1 8360
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Connection closed by foreign host.

Therefore, I plan to use the command to enter the docker container to view:

[root@hecs-205828 ~]# docker ps -a
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                       NAMES
dfb2b46abd34   httpserver:0.0.1   "/web-server/web-ser…"   27 hours ago     Up 2 hours      0.0.0.0:8360->8360/tcp, :::8360->8360/tcp   relaxed_mccarthy

Through docer ps -a, the container id is dfb2b46abd34. Enter the container:

[root@hecs-205828 ~]# docker exec -it dfb2b46abd34 sh
/web-server # ps 
PID   USER     TIME  COMMAND
    1 root      0:00 /web-server/web-server
   38 root      0:00 sh
   94 root      0:00 sh
  101 root      0:00 ps
/web-server # netstat -an |grep 8360
tcp        0      0 127.0.0.1:8360          0.0.0.0:*               LISTEN      
/web-server #

As you can see, port 8360 has actually been listened to inside the container. There should be no problem with container access. The container supports wget:

/web-server # wget -q -O -  http://127.0.0.1:8360/hello
hello http server
/web-server # 

You can see that it is normal to run inside the docker service.

Check out its network port diffraction:

[root@hecs-205828 ~]# docker port  dfb2b46abd34 
8360/tcp -> 0.0.0.0:8360
8360/tcp -> :::8360

There is no problem with port diffraction. So where exactly is the problem? Suddenly I thought that the nestat listening port inside the container was 127.0.0.1, so I immediately understood. If the listening port inside the container is 127.0.0.1, then only local loopback access from 127.0.0.1 inside the container can be accepted. Access requests from outside the container will be denied. Therefore, the reason for fixing this problem is actually very simple. You only need to change the middle listening ip to 0.0.0.0.

3. Solution

Decisively change the listening ip to 0.0.0.0:

func main() {
   ("/hello", handler_hello)
   ("/healthz", handler_healthz)
   ("0.0.0.0:8360", nil)
}

Then recreate the image:

sudo docker build . -t httpserver:0.0.2

Then start the local image:

 sudo docker run -d -p 8260:8230 httpserver:0.0.2

After startup:

[root@hecs-205828 ~]# docker ps -a
CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                       NAMES
ae5e2bf431c7   httpserver:0.0.2   "/web-server/web-ser…"   50 minutes ago   Up 50 minutes   0.0.0.0:8260->8360/tcp, :::8260->8360/tcp   affectionate_nash
dfb2b46abd34   httpserver:0.0.1   "/web-server/web-ser…"   27 hours ago     Up 2 hours      0.0.0.0:8360->8360/tcp, :::8360->8360/tcp   relaxed_mccarthy
[root@hecs-205828 ~]# 

Then access the newly added container, and the result is normal:

[root@hecs-205828 ~]# curl -XGET http://127.0.0.1:8260/hello
hello http server
[root@hecs-205828 ~]# 

Problem solved.

This is the article about solving the problem of port inaccessibility when docker deploys golang http service. This is the end of this article. For more related docker deploy golang http content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!