Docker构建的Go程序无法提供HTTP服务。

huangapple go评论94阅读模式
英文:

Docker Go build not serving HTTP server

问题

尝试为我的Go应用程序创建一个Docker容器-它在8080端口上创建一个HTTP服务器:

package main
import (
    "net/http"
)

func main() {
    http.HandleFunc("/", doX)
    if err := http.ListenAndServe("localhost:8080", nil); err != nil {
        panic(err)
    }
}

func doX(w http.ResponseWriter, r *http.Request) {
    // 处理请求的逻辑
}

当我运行go build,然后访问localhost:8080时,它可以正常工作,但是当我尝试在Docker中构建和运行它时,它没有响应:

# 从最新的golang基础镜像开始
FROM golang:1.14.3-alpine

# 设置容器内的当前工作目录
WORKDIR /app

# 将源代码从当前目录复制到容器内的工作目录
COPY /src .

# 构建Go应用程序
RUN go build -o main .

# 将端口8080暴露给外部
EXPOSE 8080

# 运行可执行文件
CMD ["./main"]

我运行的命令是:

docker build -t src .
docker run -d -p 8080:8080 src

我所有的.go文件都在一个名为'src'的目录中。感谢您的帮助-对Docker还不太熟悉,谢谢!

英文:

Trying to create a Docker container for my Go application - it creates a HTTP server on port 8080:

package main
import (
    "net/http"
)

func main() {
    http.HandleFunc("/", doX)
    if err := http.ListenAndServe("localhost:8080", nil); err != nil {
        panic(err)
    }
}

func doX(w http.ResponseWriter, r *http.Request) {
    x
}

When I run go build and then go to localhost:8080 it works, however it's unresponsive when I try building and running it in Docker:

# Start from the latest golang base image
FROM golang:1.14.3-alpine

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy the source from the current directory to the Working Directory inside the container
COPY /src .

# Build the Go app
RUN go build -o main .

# Expose port 8080 to the outside world
EXPOSE 8080

# Command to run the executable
CMD ["./main"]

The commands I'm running are:

docker build -t src .
docker run -d -p 8080:8080 src

All my .go files are in a directory called 'src'. Help appreciated - quite new to Docker, thanks!

答案1

得分: 2

将主机从localhost更改为0.0.0.0。这样就可以了。
例如:

func main() {
    http.HandleFunc("/", doX)
    if err := http.ListenAndServe("0.0.0.0:8080", nil); err != nil {
        panic(err)
    }
}

回环的主要思想是在同一主机上提供资源。如果你暴露一个端口,主机就会改变,所以它应该会抛出一个类似于connection reset by peer的错误。

或者,如果你的golang应用程序需要与其他不同镜像的容器进行通信,你可能希望创建一个网络。所以首先需要创建一个新的网络。

docker network create <network_name>

然后,在启动这个go容器以及其他容器(如果需要的话)时,传递network标志,使它们在同一个子网下可用。

docker run --network <network_name> -d -p 8080:8080 src

如果你不想这样做,可以在docker的host网络上运行容器(注意:这不是标准做法,但对于调试很有用)。如果你在host网络中使用localhosthttp.ListenAndServe运行了你的src镜像,你会立即注意到它是可访问的,但在docker的bridge网络模式下暴露端口时,它是不可访问的。所以在应用程序设置中肯定有一些错误,使其对外部网络不可见。

docker run -d --network host src

谢谢 Docker构建的Go程序无法提供HTTP服务。

英文:

change the host from localhost to 0.0.0.0. It will be fine.
i.e

func main() {
    http.HandleFunc(&quot;/&quot;, doX)
    if err := http.ListenAndServe(&quot;0.0.0.0:8080&quot;, nil); err != nil {
        panic(err)
    }
}

The main idea of loopback is serving resources on SAME HOST. if you are exposing a port, the host changes so it should throw a connection reset by peer kind of error.

Alternatively, you may wish to create a network if your golang application needs to communicate between other containers of different images.
So first a new network needs to be created.

docker network create &lt;network_name&gt; 

Then while booting this go container along with different containers(if at all required) pass the network flag to make them available under the same subnet.

docker run --network &lt;network_name&gt; -d -p 8080:8080 src

If you don't want to do that run the container on host network of docker (PS. it's not the standard practice, but good for debugging). If you have run your src image in the host network with localhost at http.ListenAndServe, you could instantly notice that it is accessible but while exposing the port on docker's bridge network mode, it's not accessible. So there must be some error in the application setup where it is invisible to the outside network.

 docker run -d --network host src

Thanks Docker构建的Go程序无法提供HTTP服务。

huangapple
  • 本文由 发表于 2021年4月29日 13:17:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/67311381.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定