Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.5k views
in Technique[技术] by (71.8m points)

mongodb - Go cannot connect to Mongo container when using docker

I would like to run 3 services:

  1. My Go program which will connect to MongoDB in another container
  2. Mongo
  3. Mongo Express

Here's my 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

As you can see, my Mongo database is mapped to port 217018, with the network name mongo.

My Golang program will take in the hostname and port through environment variables (MONGO_HST and MONGO_PRT). Here's my Go program:

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)
    }
}

After I run docker-compose, checking the logs for my Go container would result in the following message:

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

From the log, I can see that Go was trying to connect to the following address: mongo:27018, which is in fact what I would like to see.

Running docker ps, I also can see that my 2 containers mongo, mongo-express are running:

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

Any ideas? Much appreciate!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Connections between containers ignore ports:. Use the standard port for the target container, in this case the standard MongoDB port 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

Networking in Compose in the Docker documentation says a little more.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...