31

I need to create a Health Check for a MongoDB instance inside a Docker container.

Although I can make a workaround and use the Mongo Ping using the CLI, the best option is to create a simple HTTP or TCP testing. There is no response in the default 27017 port in standard ping testings.

Is there any trustworthy way to do it?

Luís Brito
  • 1,652
  • 1
  • 17
  • 34

5 Answers5

37

I've created a simple health check for mongodb, it uses the mongo client to send a simple query request (eg. db.stats()) to the server.

$ mongo 192.168.5.51:30000/test

MongoDB shell version: 3.2.3
connecting to: 192.168.5.51:30000/test

mongos> db.stats()
{
    "raw" : {
        "set1/192.168.5.52:27000,192.168.5.53:27000" : {
            "db" : "test",
            "collections" : 8,
            "objects" : 50,
            "avgObjSize" : 73.12,
            "dataSize" : 3656,
            "storageSize" : 53248,
            "numExtents" : 8,
            "indexes" : 8,
            "indexSize" : 65408,
            "fileSize" : 469762048,
            "nsSizeMB" : 16,
            "dataFileVersion" : {
                "major" : 4,
                "minor" : 6
            },
            "extentFreeList" : {
                "num" : 28,
                "totalSize" : 184807424
            },
            "ok" : 1
        }
    },
    "objects" : 50,
    "avgObjSize" : 73,
    "dataSize" : 3656,
    "storageSize" : 53248,
    "numExtents" : 8,
    "indexes" : 8,
    "indexSize" : 65408,
    "fileSize" : 469762048,
    "extentFreeList" : {
        "num" : 28,
        "totalSize" : 184807424
    },
    "ok" : 1
}

You can also do this in one line:

$ echo 'db.stats().ok' | mongo 192.168.5.51:30000/test --quiet
1

Hope it's help.

UPDATE:

As @luckydonald said, the ping command is better, so you can do it like:

$ mongo --eval 'db.runCommand("ping").ok' localhost:27017/test --quiet
1

Thanks for @luckydonald.

Shawyeok
  • 1,186
  • 1
  • 8
  • 15
  • Great! Solved my problem. – Luís Brito Jul 05 '16 at 18:25
  • 2
    What if we want to check remote db, so without `mongo` binary, instead of local one? – Kamil Dziedzic Mar 01 '17 at 16:59
  • 7
    _[This comment](https://stackoverflow.com/questions/8726152/mongodb-how-to-get-db-stats-from-api#comment13659027_8727314) warns:_ Be warned that dbstats blocks your database while it runs, so it's not suitable in production. https://jira.mongodb.org/browse/SERVER-5714 – luckydonald Nov 21 '17 at 21:57
  • 14
    A good alternative might be the [ping](https://docs.mongodb.com/manual/reference/command/ping/) command. As you might expect, it is intended to be lightweight and to return even from a server under heavy load which makes it well suited for a health check command[](https://serverfault.com/a/625493). In pymongo that's `db.command('ping')`, returning `{'ok': 1}`. – luckydonald Nov 21 '17 at 22:04
  • Tks guys, I was using db.stats() but now I'll switch to the ping command. – Luís Brito Dec 21 '17 at 18:16
  • `db.stats()` may require authentication, you may get `{ok: 0}` despite Mongo is up an running. – Wernfried Domscheit May 03 '21 at 17:21
  • the ping command takes 30 secs to timeout, how to adjust it? otherwise it's blocking the thread that sends the ping. – kakarukeys Jul 10 '21 at 01:01
18

If you need only a simple "ping" then you can also use curl:

curl --connect-timeout 10 --silent --show-error hostname:27017

If you get the "error" It looks like you are trying to access MongoDB over HTTP on the native driver port. then your MongoDB is running and replies.

Or use one of these

mongosh --norc --quiet --host=hostname:27017 <<< "db.getMongo()"
mongosh --norc --quiet --host=hostname:27017 --eval "db.getMongo()" 
echo "db.getMongo()" | mongosh --norc --quiet --host=hostname:27017

One benefit against db.stats(): Command db.getMongo() works without authentication, i.e. you don't need any credentials.

Just a note, if you run your MongoDB with SSL/TLS enabled and set nte.tls.mode: requireTLS then you must also provide according certificates, otherwise you cannot run db.getMongo(), db.runCommand("ping") or db.stats(). The curl command is most generic and works in any case.

Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
7

One solution is to use a minimal MongoDB client written in a script language for which there is an interpreter in your container.

For example, here is a zero-dependency one in Python: mongo_ping_client.py

Lucas Cimon
  • 1,859
  • 2
  • 24
  • 33
1

For MongoDB > 6.0 the healthcheck test could simply be :

test: mongosh --eval 'db.runCommand("ping").ok' --quiet
JulBeg
  • 126
  • 1
  • 6
0

telnet mongodb_server_name 28017

If the connection is successful, you will receive the following similar output from the command.

Trying 9.30.252.5... Connected to 9.30.252.5. Escape character is '^]'.

If the connection is failed,enter code here you will receive the following similar output from the terminal.

Trying 9.30.252.5... telnet: connect to address 9.30.252.5: Connection refused telnet: Unable to connect to remote host

Font: https://www.ibm.com/docs/en/db2/11.1?topic=sources-testing-network-connection-mongodb-rest-service-server