docker - 无法连接到 Docker 容器中的 Go Server

标签 docker go networking ubuntu-20.04

我正在尝试在 docker 容器内运行一个用 Golang 编写的 HTTP 服务器,但我一直收到连接被拒绝的请求。一切都在我的 Windows 10 机器上运行的 Ubuntu 20.04 服务器虚拟机中运行。

Go 服务器代码:

package main

import "github.com/lkelly93/scheduler/internal/server"

func main() {
    server := server.NewHTTPServer()
    server.Start(3000)
}
package server

import (
    "context"
    "fmt"
    "net/http"
)

type HTTPServer interface {
    Start(port int) error

    Stop() error
}

func NewHTTPServer() HTTPServer {
    return &httpServer{}
}

type httpServer struct {
    server *http.Server
}

func (server *httpServer) Start(port int) error {
    serveMux := newServeMux()
    server.server = &http.Server {
        Addr: fmt.Sprintf(":%d", port),
        Handler: serveMux,
    }
    return server.server.ListenAndServe()
}

func (server *httpServer) Stop() error {
    return server.server.Shutdown(context.Background())
}

我的 Dockerfile:

FROM ubuntu:20.04

RUN apt-get update -y

#Install needed packages
RUN apt-get install software-properties-common -y
RUN apt-get install python3 -y
RUN apt-get update -y 
RUN apt-get install python3-pip -y
RUN apt-get install default-jre -y

#Install language dependacies
    #Python
    RUN pip3 install numpy

#Reduce VM size
# RUN rm -rf /var/lib/apt/lists/*

#Setup working DIRs
RUN mkdir secure
RUN mkdir secure/runner_files

COPY scheduler /secure
WORKDIR /secure

EXPOSE 3000

CMD ["./scheduler"] <-- The go server is compiled into a binary called scheduler

我构建给定的 Dockerfile 然后运行:

docker run -d --name scheduler -p 3000:3000 scheduler:latest

然后我获取容器的地址:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' scheduler
->172.17.0.2

最后我使用 cURL 发送了一个 http 请求:

curl http://172.17.0.2:3000/execute/python --data '{"Code":"print(\"Hello\")"}'

我得到了

curl: (7) Failed to connect to 172.17.0.2 port 3000: Connection refused

但应该得到

{"Stdout":"Hello\n"}%

如果我在 Ubuntu VM 上运行 Go 服务器,我从我的 Win10 机器上调用它没有问题,但当 Go 服务器存在于 Ubuntu 机器的 docker 容器内时,我似乎无法调用它。

Go 代码比那个更复杂,但是在这里发布所有内容太多了,请随时查看整个存储库 https://github.com/lkelly93/scheduler .

最终它将成为我想要运行代码的网站的后端。类似于 LeetCode 或 Repl.it。

谢谢!

编辑:

docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
2a56a973040f        scheduler:latest    "./scheduler"       37 seconds ago      Up 36 seconds       0.0.0.0:3000->3000/tcp   scheduler

docker 容器日志 2a56a973040f 没有输出。

编辑 2:

docker run -it --net container:2a56a973040f nicolaka/netshoot ss -lnt
State  Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0      4096               *:3000            *:*

编辑 3:

阅读手册页后,我发现如果我有标签 --network=host 到我的图像然后运行。

curl http://localhost:3000/execute/python --data '{"Code":"print(\"Hello\")"}'

我得到了正确的输出。虽然这可行,但我希望同时运行多个 docker 图像。所以我更愿意使用 IP 地址来解决所有这些问题。所以我认为这不是永久性的解决方案。

最佳答案

为了在我的服务器上解决这个问题,我将 IP 地址设置为 0.0.0.0:4000。 我正在使用 Gin ,所以这个例子看起来像:

r := gin.Default()
r.run("0.0.0.0:4000")

在此之后,我终于可以通过浏览器访问它了。

关于docker - 无法连接到 Docker 容器中的 Go Server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63769426/

相关文章:

loops - 在 GO 模板中使用 range over struct

go - IP 地址从 maxAddress 开始

iphone - iOS ping 和 ttl 超时

networking - 如何将基于主机名的请求转发到特定的 docker 容器

java - 无法从容器外部运行的 Spring Boot 应用程序连接到容器中运行的 Kafka

linux - 无法在 Linux 上使用绝对路径创建 Docker 卷

Java 套接字 - 如何确定服务器端的数据类型?

Docker-重复的挂载点

Go:提供 html 模板时出错

java - 同时来自多台计算机/用户的 Eclipse?