func GetDatabase() (database *mongo.Database, ctx context.Context, err error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://mongodb:27017"))
if err != nil {
log.Println("database connection error", err)
return nil, nil, err
}
err = client.Ping(context.TODO(), readpref.Primary())
if err != nil {
log.Println("err", err)
return
}
log.Println("Successfully connected and pinged.")
dbName := GetDatabaseName()
database = client.Database(dbName)
log.Println(dbName, database.Name())
return
}
This golang app is running on one container and mongodb on other.
Above is my function for checking the database connection. After reading some suggestions on internet I am trying to use container name instead of localhost.
Please provide your inputs on Dockerfile or docker-compose file.
Dockerfile
FROM golang:1.18 AS builder
WORKDIR /app
COPY . .
ENV CGO_ENABLED=0
RUN go build -o main .
FROM alpine:latest
COPY --from=builder /app ./
EXPOSE 8080
ENTRYPOINT ["./main"]
docker-compose
version: '3.7'
services:
db:
image: mongo
restart: always
platform: linux/x86_64
networks:
- default
ports:
- "27017:27017"
container_name: mongodb
api:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
depends_on:
- db
on running these two containers, app container will give db connection error.
2
Answers
As pointed out in the comment and the answer by oren. You have 2 issues.
You will see that the app reports that it has connected and the shuts down.
There might be a better way to do health checks on the db, I am no mongodb expert, so you have to research if there is something.
Another thought is, that it may be better to build some kind of retry logic and health checks into your application. So that it retries to connect to the db and reports if there is currently no connection.
Depending on the kind of service you are building, this may or may not make sense. If you have a simple job that needs to run a one time task, it would make sense to wait for the db. If you have something like a rest API, health checks could make more sense.
For example:
You have the correct service name. As been said here, you can use both
db
ormongodb
as the host name. (You don’t need to set a user and pass…)But you have a bug in the code. You only initialize a new client, you don’t connect to it. You can use
Connect
instead ofNewClient
, or doclient.Connect
.Also, you are using
context.Todo
instead of thectx
with the timeout (Not a biggy, but still).You should do this: