I want to use Typesense with Mongodb. To do so I first need to enable replicaset.
From what I read here and there, to achieve it with docker compose, it must be done in two steps, like this :
version: '3.8'
services:
mongodb:
image: mongo
container_name: 'mongodb'
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
MONGO_INITDB_DATABASE: testDb
volumes:
- ./mongodb-config/mongod.test.conf:/etc/mongod.conf:ro
- ./mongodb-config/keyfile:/test/keyfile
ports:
- '27017:27017'
expose:
- '27017'
entrypoint:
- bash
- -c
- |
chmod 400 /test/keyfile
chown 999:999 /test/keyfile
exec docker-entrypoint.sh $$#
command: mongod --replSet testRs --keyFile /test/keyfile --bind_ip localhost;
mongosetup:
image: mongo
depends_on:
- mongodb
restart: 'no'
entrypoint:
[
'bash',
'-c',
"sleep 10 && mongo admin --host mongodb:27017 -u root -p example --verbose --eval 'rs.initiate()'",
]
log from mongosetup :
MongoDB shell version v5.0.9
connecting to: mongodb://mongodb:27017/admin?compressors=disabled&gssapiServiceName=mongodb
{"t":{"$date":"2022-07-20T14:58:50.437Z"},"s":"D1", "c":"NETWORK", "id":20109, "ctx":"js","msg":"Creating new connection","attr":{"hostAndPort":"mongodb:27017"}}
{"t":{"$date":"2022-07-20T14:58:50.440Z"},"s":"D1", "c":"-", "id":23074, "ctx":"js","msg":"User assertion","attr":{"error":"InternalError: couldn't connect to server mongodb:27017, connection attempt failed: SocketException: Error connecting to mongodb:27017 (192.168.0.2:27017) :: caused by :: Connection refused","file":"src/mongo/scripting/mozjs/mongo.cpp","line":745}}
Error: couldn't connect to server mongodb:27017, connection attempt failed: SocketException: Error connecting to mongodb:27017 (192.168.0.2:27017) :: caused by :: Connection refused :
connect#src/mongo/shell/mongo.js:372:17
#(connect):2:6
{"t":{"$date":"2022-07-20T14:58:50.441Z"},"s":"D1", "c":"-", "id":23074, "ctx":"js","msg":"User assertion","attr":{"error":"Location12513: connect failed","file":"src/mongo/shell/shell_utils.cpp","line":537}}
{"t":{"$date":"2022-07-20T14:58:50.441Z"},"s":"I", "c":"QUERY", "id":22787, "ctx":"js","msg":"MozJS GC heap stats","attr":{"phase":"prologue","total":4799817,"limit":0}}
{"t":{"$date":"2022-07-20T14:58:50.444Z"},"s":"I", "c":"QUERY", "id":22787, "ctx":"js","msg":"MozJS GC heap stats","attr":{"phase":"epilogue","total":153,"limit":0}}
{"t":{"$date":"2022-07-20T14:58:50.444Z"},"s":"D1", "c":"-", "id":23074, "ctx":"main","msg":"User assertion","attr":{"error":"Location12513: connect failed","file":"src/mongo/scripting/mozjs/proxyscope.cpp","line":310}}
exception: connect failed
exiting with code 1
There must be something wrong with my way to try to connect, because I can do that manually without any problem :
docker exec -it 0188651cfb4b5789e832226094dae48fb8efd92fc318ce7b0286312f9a3d81de bash
root#0188651cfb4b:/# mongosh -u root -p example
test> rs.initiate()
{
info2: 'no configuration specified. Using a default configuration for the set',
me: 'localhost:27017',
ok: 1
}
testRs [direct: other] test>
I must be missing something, and since I'm a beginner with docker & mongo, I'm stuck :(
Thanks for your help
--bind_ip localhost in the command of mongodb container tells mongo to listen on local interface only. Try to connect to it from mongosetup manually and you will face the same error.
Use --bind_ip_all option instead.
I'm trying to create a docker file that mongo running in a different container, to execute commands from a file, however the second container receives a connection refused error:
mongo-testdata_1 | MongoDB shell version: 3.2.9
mongo-testdata_1 | connecting to: mongo:27017/admin
mongo-testdata_1 | 2019-12-15T15:57:30.067+0000 W NETWORK [thread1] Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused
mongo-testdata_1 | 2019-12-15T15:57:30.067+0000 E QUERY [thread1] Error: couldn't connect to server 127.0.0.1:27017, connection attempt failed :
mongo-testdata_1 | #./testData.js:1:20
mongo-testdata_1 |
mongo-testdata_1 | failed to load: ./testData.js
How would I be able to connect to the mongoDB running on the first container, using the mongo cli in the second?
commands used
docker-compose up -d mongo
docker exec my-test-mongo mongo --eval "db.createUser({ user: 'admin', pwd: 'password', roles: [ 'dbAdmin', 'readWrite' ] });" admin
docker-compose up --build mongo-testdata
mongo.dockerfile
FROM mongo:3.2.9
ADD testData.js .
ENTRYPOINT ["mongo"]
docker-compose.yml
version: '2'
services:
mongo-testdata:
build:
context: .
dockerfile: mongo.dockerfile
command: --host mongo --port 27017 --username='admin' --password='password' admin ./testData.js
depends_on:
- mongo
networks:
- backend
mongo:
image: mongo:3.2.9
container_name: my-test-mongo
ports:
- 27017:27017
networks:
- backend
networks:
backend:
driver: bridge
testData.js
const myDb = new Mongo().getDB('mydb');
myDb.getCollection('test').insert({
foo: 'bar',
});
You need to specify host and port when you connect to mongo in testData.js.
new Mongo(<host:port>)
In your case this would be new Mongo('mongo').
https://docs.mongodb.com/v3.2/reference/method/Mongo/#Mongo
Instantiation Options
Use the constructor without a parameter to instantiate a connection to the localhost interface on the default port.
Pass the parameter to the constructor to instantiate a connection to the and the default port.
Pass the <:port> parameter to the constructor to instantiate a connection to the and the .
The only depends_on will not work, as the mongo DB container process is not ready to accept to container while CLI get connection refused. You can try two option
- simply put sleep for some second the DB container will ready to accept connection
- Increase wait timeout in mongo shell connection
Here is way to deal with connection refused by adding 10 second seelp in import.
version: '2'
services:
mongo_import:
image: mongo
command: /bin/bash -c "sleep 10 && mongo --host mongo --port 27017 --username='admin' --password='password' admin /root/testData.js"
volumes:
- ./testData.js:/root/testData.js
depends_on:
- mongo
mongo:
image: mongo
container_name: my-test-mongo
ports:
- 27017:27017
Btw the above task you can perform in the same container without the need of any cli container.
Initializing a fresh instance
When a container is started for the first time it will execute files
with extensions .sh and .js that are found in
/docker-entrypoint-initdb.d. Files will be executed in alphabetical
order. .js files will be executed by mongo using the database
specified by the MONGO_INITDB_DATABASE variable, if it is present, or
test otherwise. You may also switch databases within the .js script.
Initializing a fresh instance
I'm trying to deploy a minimal mongodb cluster into my development swarm environment like this:
Up to now:
version: "3.3"
networks:
net:
driver: overlay
services:
data1:
image: mongo:3.6
container_name: data1
command: mongod --shardsvr --replSet datars --smallfiles --port 27017
expose:
- 27017
networks:
- net
cfg1:
image: mongo:3.6
container_name: cfg1
command: mongod --configsvr --replSet cfgrs --smallfiles --port 27017
expose:
- 27017
networks:
- net
mongos1:
image: mongo:3.4
container_name: mongos1
command: mongos --configdb cfgrs/cfg1:27017
expose:
- 27017
networks:
- net
Into my config server, I'm getting these message:
2019-09-06T09:22:15.693+0000 I SHARDING [shard registry reload] Periodic reload of shard registry failed :: caused by :: 134 could not get updated shard list from config server due to Read concern majority reads are currently not possible.; will retry after 30s,
Any ideas?
I'm running my mongo db with docker-compose
version: '3'
services:
db:
image: mongo:4
ports:
- "27017:27017"
volumes:
- ./storage/mongo:/data/db:rw
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=admin123
command: --smallfiles --bind_ip_all --port 27017
When I do
$> docker-compose exec db bash
I can simply connect to my db
$> mongo -u admin -p admin123
However, when I do the same thing from my host system I cannot connect
(master) ✗ mongo -u admin -p admin123
MongoDB shell version v4.0.3
connecting to: mongodb://127.0.0.1:27017
Implicit session: session { "id" : UUID("8689631e-ac9c-40f8-aa2a-e55f6103224f") }
MongoDB server version: 4.0.9
2019-05-11T17:44:19.181+0200 E QUERY [js] Error: Authentication failed. :
DB.prototype._authOrThrow#src/mongo/shell/db.js:1685:20
#(auth):6:1
#(auth):1:2
exception: login failed
I also tried with --host 0.0.0.0 but same result. Below is the listing of ps
$> docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------------------------------------------
db_1 docker-entrypoint.sh --sma ... Up 0.0.0.0:27017->27017/tcp
I get the feeling that mongo doesn't accept remote connections, which is why I added command: --smallfiles --bind_ip_all --port 27017 but it didn't help. Any suggestion what I'm doing wrong?
I'm trying to create a Mongo ReplicaSet running locally, using the following docker-compose file:
version: '2.0'
services:
db01:
image: mongo:3.4
mem_limit: 512m
restart: always
ports:
- "27017:27017"
volumes:
- datadb01:/data/db
- ./etc/mongod.conf:/etc/mongod.conf
command: mongod --smallfiles --noIndexBuildRetry --replSet rs0
container_name: db01
networks:
- mongo
db02:
image: mongo:3.4
mem_limit: 512m
restart: always
ports:
- "27018:27017"
volumes:
- datadb02:/data1/db
- ./etc/mongod.conf:/etc/mongod.conf
command: mongod --smallfiles --noIndexBuildRetry --replSet rs0
container_name: db02
networks:
- mongo
So this actually seems to work! I won't post the whole thing but when I run rs.status() I get this:
{
"set" : "rs0",
...
"ok" : 1
}
However, when I try to connect to the replicaSet, rather than just a single node, I get this bunch of error logs:
~/utils/infrastructure/content-repl-set [replay-content*]: mongo --host rs0/127.0.0.1:27017,127.0.0.1:27018
MongoDB shell version v4.0.0
connecting to: mongodb://127.0.0.1:27017,127.0.0.1:27018/?replicaSet=rs0
2018-09-10T17:50:42.173-0400 I NETWORK [js] Starting new replica set monitor for rs0/127.0.0.1:27017,127.0.0.1:27018
2018-09-10T17:50:42.176-0400 I NETWORK [js] Successfully connected to 127.0.0.1:27018 (1 connections now open to 127.0.0.1:27018 with a 5 second timeout)
2018-09-10T17:50:42.177-0400 I NETWORK [js] changing hosts to rs0/db01:27017,db02:27017 from rs0/127.0.0.1:27017,127.0.0.1:27018
2018-09-10T17:50:42.177-0400 I NETWORK [ReplicaSetMonitor-TaskExecutor] Successfully connected to 127.0.0.1:27017 (1 connections now open to 127.0.0.1:27017 with a 5 second timeout)
2018-09-10T17:50:42.684-0400 W NETWORK [js] Unable to reach primary for set rs0
My best guess from that is that the mongo shell (and other mongo drivers, such as pymongo) isn't aware of the container name that I've specified in the docker container. Is there a way to expose this information to my local machine? Or am I off the mark? Thanks for your help
Are you using MacOS? if so, it seems those internal IP addresses in docker are unreachable because the docker (Linux) bridge network is not reachable from the macOS host.
More of it here: https://docs.docker.com/docker-for-mac/networking/