How to set up Mongo replica set in dockerfile mode - mongodb

I created a dockerfile file to build the Mongo replica set.It is not a problem to start creating a copy set, but when configuring a copy of Mongo, I don't want to manually go into the Mongo shell default configuration, which is too troublesome, so I automatically execute a script to complete automatic configuration when creating docker, and try a lot of methods, the following my specific way is not running. Work
And run a script The following is my detailed document
dockerfile
FROM mongo:3.4
ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
COPY ./setup.js /docker-entrypoint-initdb.d/
RUN chmod +x /docker-entrypoint-initdb.d/setup.js
ENTRYPOINT ["/docker-entrypoint-initdb.d/setup.js"]
setup.js
#!/bin/bash
echo "Started.."
mongod --replSet replset0
mongo 127.0.0.1/admin -u test -p test --authenticationDatabase "admin"<<EOF
var cfg = {
"_id": "replset0",
"members": [
{
"_id": 0,
"host": "192.168.1.233:27018"
}
]
};
rs.initiate(cfg, { force: true });
rs.reconfig(cfg, { force: true });
EOF
exec "$#"
After executing the mongod --replSet replset0, mongo Unable to execute.I want to know what you can do. Thank you very much.

Related

Create mongo image having initial collections with docker file

I am trying to create a custom mongo image from the official image with few custom collections baked into the image.
I have created a init script that runs and import json into the database using mongoimport.
Docker file builds correctly and I can see the scripts runs successfully.
But when i run the container with the generated image I am unable to see the added collecitons.
Docker file:
FROM mongo:latest
RUN mkdir -p /data/db2 \
&& echo "dbpath = /data/db2" > /etc/mongodb.conf \
&& chown -R mongodb:mongodb /data/db2
COPY ./upload.json /json/
COPY ./init.sh .
RUN ./init.sh
VOLUME /data/db2
CMD ["mongod", "--config", "/etc/mongodb.conf"]
#docker build -f Dockerfile -t my-mongo/test:1.0 .
init.sh:
#!/usr/bin/env bash
mongod --fork --logpath /var/log/mongodb.log --dbpath /data/db2
mongoimport -d testStore -c authors --file ./json/upload.json --jsonArray
mongod --dbpath /data/db2 --shutdown
upload.json:
[
{ "Name": "Design Patterns", "Price": 54.93, "Category": "Computers", "Author": "Ralph Johnson" },
{ "Name": "Clean Code", "Price": 43.15, "Category": "Computers", "Author": "Robert C. Martin" }
]

Bash script to create a replica set

I am working on a replicaSet mongo in aws, my goal is to set the replica in run time with a bash script command.
my bash look like this:
mongo mongodb://10.0.1.100 --eval "rs.initiate( { _id : 'rs0', members: [{ _id: 0, host: '10.0.1.100:27017' }]})"
mongo mongodb://10.0.1.100 --eval "rs.add( '10.0.2.100:27017' )"
mongo mongodb://10.0.1.100 --eval "rs.add( '10.0.3.100:27017' )"
mongo mongodb://10.0.1.100 --eval "db.isMaster().primary"
mongo mongodb://10.0.1.100 --eval "rs.slaveOk()"
but when i log in my instance and run rs.status(), i get the error that no config could be found.
So i tried in a different way. I accessed my fresh mongo instance, and through themongo command line i inserted the var config such as:
var config={_id:"rs0",members:[{_id:0,host:"10.0.1.100:27017"}, {_id:1,host:"10.0.2.100:27017"}, {_id:2,host:"10.0.3.100:27017"}]};
> rs.initiate(config);
if i run rs.status, it works.
i would like to run the same command through a linux bash command script to initiate the config, but i cant find a solution. any help please?

Create indexes on initdb script

I have a custom docker image from mongo:4.2-6-bionic with two initdb scripts:
/docker-entrypoint-initdb.d/1-database-seed.sh
/docker-entrypoint-initdb.d/2-create-indexes.sh
When the image is created, the 1-database-seed.sh file is executed correctly. But, 2-create-indexes.sh is not executed.
If i execute manually 2-create-indexes.sh, inside the container, the script runs correctly. The script content is:
#!/bin/bash
mongo renaper --eval "db.names_indexed.createIndex({'fullname': 1})";
mongo renaper --eval "db.names_indexed.createIndex({'year': 1})";
mongo renaper --eval "db.names_indexed.createIndex({'fullname': 1,'year': 1})";
mongo renaper --eval "db.names_indexed.createIndex({'fullname': 'text'})";
Any ideas ?
Finally, I put all the tasks in a single file and it worked correctly.

Customize mongo docker raise an error when I try to create a new user for database

I am using a mongo docker image. When I trying to create a user and password for a new database I get an error.
It is my Dockerfile:
FROM mongo
ENV AUTH yes
ENV JOURNALING yes
ADD run.sh /usr/bin/run.sh
ADD set_mongodb_password.sh /usr/bin/set_mongodb_password.sh
RUN chmod +x /usr/bin/run.sh && chmod +x /usr/bin/set_mongodb_password.sh
EXPOSE 27017 28017
CMD ["/usr/bin/run.sh"]
Ok, Now my run script:
#!/bin/bash
cmd="mongod"
if [ "$AUTH" == "yes" ]; then
cmd="$cmd --auth"
fi
if [ "$JOURNALING" == "no" ]; then
cmd="$cmd --nojournal"
fi
$cmd &
if [ ! -f /data/db/.mongodb_password_set ]; then
set_mongodb_password
fi
fg
and my set_mongodb_password script:
#!/bin/bash
USER=${MONGO_USER:-"mongo"}
PASS=${MONGO_PASSWORD:-"mongo"}
DB=${MONGO_DB:-"testdb"}
echo "=> Creating database < ${DB} > with an user < ${USER} > and password < ${PASS} > in MongoDB"
echo "=> Creating database"
mongo $DB --eval "db.getSiblingDB('${DB}');"
echo "=> Creating user and password"
mongo $DB --eval "db.createUser({user: '${USER}', pwd: '${PASS}', roles:[ { role:'readWrite',db: '${DB}'} ] } ) ;"
#mongo admin --eval "db.createUser({user: 'mongo', pwd: '${PASS}', roles:[{role:'readWrite',db:'$DB'}]});"
echo "=> Done!"
touch /data/db/.mongodb_password_set
echo "========================================================================"
echo "You can now connect to this MongoDB server using:"
echo ""
echo " mongo ${DB} -u ${USER} -p ${PASS} --host <host> --port <port>"
echo ""
echo "Please remember to change the above password as soon as possible!"
echo "========================================================================"
I build and create my mongo image, so when I try to connect with the user and password it return an authentication error. Then I go inside of my mongo container with the docker exec command and run the set_mongodb_password script manually, I got the follow error:
2015-08-05T06:08:50.550+0000 E QUERY Error: couldn't add user: not authorized on pepedb to execute command { createUser: "pepe", pwd: "xxx", roles: [ { role: "readWrite", db: "pepedb" } ], digestPassword: false, writeConcern: { w: "majority", wtimeout: 30000.0 } }
at Error (<anonymous>)
at DB.createUser (src/mongo/shell/db.js:1101:11)
at (shell eval):1:4 at src/mongo/shell/db.js:1101
So, I don't know how to solve this error. When I use the simple mongo image and run it. I can go inside the container and run the content of my set_mongodb_password script steps by steps and everything work fine. So I don't understand where is the problem. Maybe I am missing something in the configuration or some mongo parameters. Any help please ?
You have some errors in run.sh and set_mongodb_password.sh.
In script run.sh you need to add "set -m" right after the line #!bash, because in the last line you use fg. Read the post https://unix.stackexchange.com/questions/196603/can-someone-explain-in-detail-what-set-m-does to understand "set -m" and "fg".
In the same script you need to call set_mongodb_password like /usr/bin/set_mongodb_password.sh instead of set_mongodb_password
The problem of the set_mongodb_password.sh is that it run before run.sh, so you need to add the line below after "#!bash" to wait the mongo goes up:
RET=1
while [[ RET -ne 0 ]]; do
echo "=> Waiting for confirmation of MongoDB service startup"
sleep 5
mongo admin --eval "help" >/dev/null 2>&1
RET=$?
done
After doing this you will be able to execute mongo commands and create the user you need.

How to set permernent dbpath for mongodb

I understand that mongo db need to be started before I can interact with it. But what I don't understand why do I set the dbpath every time? I thought we only need to configure that path once. Am I correct?
You can solve this two ways:
change your dbpath to the hard coded one which will point to /data/db/
Or make a startup script that will actually call the MongoDB instance for you
You could make a few scripts, as I said in my last point, to do this for you, as an example:
=== rnMongo.sh ===
./mongod --dbpath
Then with a single command:
./rnMongo.sh
Or as an upstart job:
# mongodb - Mongo Starter
author "lol"
description "Starts the MongoDB servers"
start on started network-services
#expect fork
exec /home/ubuntu/mongodb/bin/mongod --auth
#echo "Mongodb is now running";
#exit 0;
#stop
stop on runlevel [016]
#pre-stop
Something along those lines
Just add mongod --dbpath /home/user/mongodb to your startup applications ;)
sudo mongod --port portnumber --dbpath /path to your folder
By default it is set to
sudo mongod --port 27017 --dbpath /var/lib/mongodb