使用 docker 时 Go 无法连接到 Mongo 容器

时间:2021-01-23 03:59:55

标签: mongodb docker go

我想运行 3 个服务:

  1. 我的 Go 程序将连接到另一个容器中的 MongoDB
  2. 蒙哥
  3. Mongo Express

这是我的 docker-compose.yml:

version: "3.7"

services:
  app:
    image: test-go-docker
    environment:
      - MONGO_HST=mongo
      - MONGO_PRT=27018

  mongo:
    image: mongo
    ports:
    - 27018:27017
    volumes:
    - /data/db

  mongo-express:
    image: mongo-express
    ports:
    - 8081:8081

如您所见,我的 Mongo 数据库映射到端口 217018,网络名称为 mongo。

我的 Golang 程序将通过环境变量(MONGO_HST 和 MONGO_PRT)获取主机名和端口。这是我的 Go 程序:

package main

import (
    "context"
    "fmt"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "net/http"
    "os"
    "time"
)

type MyData struct {
    Name string
    Text string
}

func viewHandler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello world!")
}

func main() {
    mongoURI := "mongodb://" + os.Getenv("MONGO_HST") + ":" + os.Getenv("MONGO_PRT") + "/"
    client, err := mongo.NewClient(options.Client().ApplyURI(mongoURI))
    must(err)

    ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
    defer cancel()

    err = client.Connect(ctx)

    collection := client.Database("test_db").Collection("test_collection")
    data := MyData{
        Name: "testing...",
        Text: "Hello world",
    }

    _, err =collection.InsertOne(context.Background(), data)
    must(err)

    // Serve the page
    http.HandleFunc("/", viewHandler)
    err = http.ListenAndServe(":8000", nil)
    must(err)
}

func must(err error) {
    if err != nil {
        fmt.Println("Some error...")
        panic(err)
    }
}

运行 docker-compose 后,检查 Go 容器的日志将导致以下消息:

Some error...
panic: server selection error: server selection timeout, current topology: { Type: Unknown, Servers: [{ Addr: mongo:27018, Type: Unknown, State: Connected, Average RTT: 0, Last error: connection() : dial tcp 172.25.0.4:27018: connect: connection refused }, ] }

goroutine 1 [running]:
main.must(0xccfce0, 0xc0002dd000)
        /go/src/my_app/cmd/main.go:50 +0xae
main.main()
        /go/src/my_app/cmd/main.go:39 +0x35d

从日志中可以看出,Go 尝试连接到以下地址:mongo:27018,这实际上是我想看到的。

运行 docker ps,我还可以看到我的 2 个容器 mongo、mongo-express 正在运行:

29533908c7fc   mongo           "docker-entrypoint.s…"   50 minutes ago   Up 50 minutes   0.0.0.0:27018->27017/tcp   go-with-docker_mongo_1
f4789b54ddbd   mongo-express   "tini -- /docker-ent…"   50 minutes ago   Up 50 minutes   0.0.0.0:8081->8081/tcp     go-with-docker_mongo-express_1

有什么想法吗?非常感谢!

1 个答案:

答案 0 :(得分:0)

容器之间的连接忽略ports:。使用目标容器的标准端口,在本例中为标准 MongoDB 端口 27017。

services:
  app:
    environment:
      - MONGO_PRT=27017 # the standard port

  mongo:
    image: mongo
    # ports:            # not used for connections between containers
    # - 27018:27017     # only from outside Docker
Docker 文档中的

Networking in Compose 说得更多。

相关问题