dockergocontainersgo-gin

Docker container localhost not exposed


When starting a gin server, I was using router.Run("localhost:8080").

Afterwards, running the docker command docker run -p 8080:8080 <IMAGE_NAME> does not expose the service to my local machine.

It only worked after I changed it to router.Run("0.0.0.0:8080"). Is there a difference between localhost and 0.0.0.0? If so, what is the difference in context of a docker container?

I am expecting that localhost is the same as 0.0.0.0 as that is the behaviour on my local machine during development.

My main function is below

func main() {
    fmt.Println("hello world")

    router := gin.Default()

    router.Use(middlewares.CORSMiddleware())
    router.POST("/api/notify", notify.NotifyHandler)

    // router.Run("localhost:8080")
    router.Run("0.0.0.0:8080")
}

Solution

  • In the context of networking, there is a significant difference between localhost and 0.0.0.0, especially when dealing with Docker containers.

    In the context of a Docker container, using localhost only makes the service available within the container itself. If you want to expose the service to the host machine or other devices, you need to use 0.0.0.0.

    When you run a Docker container with the -p option (e.g., docker run -p 8080:8080 <IMAGE_NAME>), you are binding a port on the host machine to a port in the container. In this case, the syntax -p HOST_PORT:CONTAINER_PORT indicates that any incoming traffic to the host's HOST_PORT will be forwarded to the container's CONTAINER_PORT.

    So, if you use router.Run("0.0.0.0:8080"), the server in the container listens on all interfaces and accepts incoming connections from the host's 8080 port, which is then forwarded to the container's 8080 port.

    In summary, the key difference is that 0.0.0.0 allows you to expose your service beyond the container's boundary, making it accessible from the host machine and other devices, while localhost confines the service to the container itself.