How to check if mongodb is ready and ready to accept connections from bash script?

I have a Bash shell script that does a bunch of things before trying mongorestore .

I want to make sure that not only MongoDB is working, but also ready to accept connections before I try to restore.

Right now, I see that the mongo process is running, but it takes 45+ seconds to complete the initial setup (setting up the log files, etc.) before it is ready to accept the connections. Ideally, I want to continue to test the connection in a loop, and only when I can connect do I want to start mongorestore .

Can someone show me how to do this in Bash or point me in the right direction?

+10
source share
5 answers

I had the same issue recently. I decided to configure mongod to register all its output to the log file and then wait in the loop to check the log file until we see some output that suggests that mongod is ready.

This is the sample logfile output we should expect:

 Tue Dec 3 14:25:28.217 [initandlisten] waiting for connections on port 27017 

This is a bash script I came up with:

  #! / bin / bash

 # Initialize a mongo data folder and logfile
 mkdir -p / data / db
 touch /var/log/mongodb.log

 # Start mongodb with logging
 # --logpath Without this mongod will output all log information to the standard output.
 # --logappend Ensure mongod appends new entries to the end of the logfile.  We create it first so that the below tail always finds something
 / usr / bin / mongod --quiet --logpath /var/log/mongodb.log --logappend &

 # Wait until mongo logs that it ready (or timeout after 60s)
 COUNTER = 0
 grep -q 'waiting for connections on port' /var/log/mongodb.log
 while [[$?  -ne 0 && $ COUNTER -lt 60]];  do
     sleep 2
     let COUNTER + = 2
     echo "Waiting for mongo to initialize ... ($ COUNTER seconds so far)"
     grep -q 'waiting for connections on port' /var/log/mongodb.log
 done

 # Now we know mongo is ready and can continue with other commands
 ...

Please note that the script will not wait forever, it will expire after 60 seconds - you may or may not want this depending on your use case.

+7
source

To test the connection in a loop, as you suggest,

 until nc -z localhost 27017 do sleep 1 done 
+19
source

Solution using MongoDB tools. Useful in a docker container or something similar where you don't want to install nc .

 until mongo --eval "print(\"waited for connection\")" do sleep 60 done 

Based on this answer of another guy.

+7
source

While Tom's answer will work very well in most situations, it may fail if you use a script with the -e flag. I mean, you are running a script with set -e at the very top. What for? Since Tom's answer relies on the exit status of the previous command, in this case grep -q , which will fail if it does not find the desired line, and therefore the whole script will fail. The -e flag documentation gives an idea of ​​how to avoid this problem:

A failure does not end if a command that does not work is part of the list of commands immediately after some time or until the keyword, part of the test in the if statement, part of any command executed in && or || a list, with the exception of the command following the final && or ||, any command in the pipeline, but the last one, or if the return status of the commands is inverted with ..

So, one solution is to make the grep command a while condition command. However, since it launches mongodb with the --logappend option, the search string may appear as a result of a previous run. I coincided with the other guy responding with Tom's answer, and it works very well:

 # Wait until mongo logs that it ready (or timeout after 60s) COUNTER=0 while !(nc -z localhost 27017) && [[ $COUNTER -lt 60 ]] ; do sleep 2 let COUNTER+=2 echo "Waiting for mongo to initialize... ($COUNTER seconds so far)" done 

I find that using tomcat is the best solution because it really checks if there is something listening.

+4
source

I needed to run Mongo in Docker to initialize before creating the user. I combined the answers of Tom and Björn. This is the script I'm using:

 #!/bin/bash # Wait until Mongo is ready to accept connections, exit if this does not happen within 30 seconds COUNTER=0 until mongo --host ${MONGO_HOST} --eval "printjson(db.serverStatus())" do sleep 1 COUNTER=$((COUNTER+1)) if [[ ${COUNTER} -eq 30 ]]; then echo "MongoDB did not initialize within 30 seconds, exiting" exit 2 fi echo "Waiting for MongoDB to initialize... ${COUNTER}/30" done # Connect to the MongoDB and execute the create users script mongo ${FWRD_API_DB} /root/create-user.js --host ${MONGO_HOST} -u ${MONGO_ROOT_USER} -p ${MONGO_ROOT_PASSWORD} --authenticationDatabase admin 
0
source

All Articles