Recently a client asked me to setup multiple instances of MongoDB on a Linux Ubuntu server. Ubuntu does not use standard /etc/init.d/ scripts, instead it uses upstart, an event-based replacement for the /sbin/init daemon, that handles starting of tasks and services during boot, stopping them during shutdown and supervising them while the system is running. Upstart uses it’s own limited syntax to describe a service or task. I tried launching several processes from a single upstart config, but upstart could not track the service properly. Instead, I broke-up the upstart script into two — one master to define the instances, and another to start each one independently.
The first part of this setup involved creating a mongodb configuration file for each instance. I decided to put them in /etc/mongodb.d/ and name them rs0-0.conf, rs0-1.conf, and rs0-3.conf (rs for replica set). The configuration file for /etc/mongodb.d/rs0-0.conf contains the following options:
1 2 3 4 5 6 7 8 9 10 |
dbpath = /srv/mongodb/rs0-0 logpath = /var/log/mongodb/rs0-0.log pidfilepath = /var/run/mongodb/rs0-0.pid logappend = true port = 27017 replSet = rs0 oplogSize = 128 smallfiles = true |
These new mongodb upstart scripts will use the /etc/mongodb.conf file (if present), and any other file ending in .conf under /etc/mongodb.d/. This means the scripts will work with the default single-instance mongodb configuration as well. It’s important to avoid using the ‘fork’ option in the mongodb configuration files — this will break upstart’s ability to track the process ID.
All instances of mongodb can be started / stopped using the standard upstart syntax (“start mongodb” and “stop mongodb”), and when running, the upstart processes list looks like this:
1 2 3 4 5 6 7 |
# initctl list | grep mongodb mongodb-instance (/etc/mongodb.d/rs0-0.conf) start/running, process 7497 mongodb-instance (/etc/mongodb.d/rs0-1.conf) start/running, process 7501 mongodb-instance (/etc/mongodb.d/rs0-2.conf) start/running, process 7505 mongodb start/running |
A single instance can also be started / stopped using this syntax:
1 2 3 4 5 6 7 8 9 |
# stop mongodb-instance CONFIG=/etc/mongodb.d/rs0-2.conf mongodb-instance stop/waiting # initctl list | grep mongodb mongodb-instance (/etc/mongodb.d/rs0-0.conf) start/running, process 7497 mongodb-instance (/etc/mongodb.d/rs0-1.conf) start/running, process 7501 mongodb start/running |
The following upstart scripts should be saved under /etc/init/mongodb.conf and /etc/init/mongodb.conf. To start mongodb automatically when the system boots, a symbolic link should be created (if it doesn’t already exist) under /etc/init.d/mongodb.
1 2 3 4 5 6 |
# ls -al /etc/init/mongodb* /etc/init.d/mongodb lrwxrwxrwx 1 root root 21 Jul 31 18:55 /etc/init.d/mongodb -> /lib/init/upstart-job -rw-r--r-- 1 root root 779 Aug 1 12:50 /etc/init/mongodb.conf -rw-r--r-- 1 root root 546 Aug 1 12:51 /etc/init/mongodb-instance.conf |
The following mongodb.conf file should be placed in /etc/init/.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# Ubuntu upstart file at /etc/init/mongodb.conf start on runlevel [2345] stop on runlevel [06] pre-start script ENABLE_MONGODB="yes" # default value [ -f /etc/default/mongodb ] && . /etc/default/mongodb if [ "$ENABLE_MONGODB" = "yes" ] then for dir in /var/lib /var/log /var/run do if [ ! -d "$dir/mongodb" ] then mkdir -p "$dir/mongodb" chown mongodb:mongodb "$dir/mongodb" fi done for CONFIG in /etc/mongodb.conf /etc/mongodb.d/*.conf do if [ -f "$CONFIG" ] then start mongodb-instance CONFIG="$CONFIG" || : fi done fi end script post-stop script for CONFIG in `initctl list|sed -n 's/^mongodb-instance (\(.*\)).*$/\1/p'` do if [ -f "$CONFIG" ] then stop mongodb-instance CONFIG="$CONFIG" || : fi done end script |
The following mongodb-instance.conf file should be placed in /etc/init/.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# Ubuntu upstart file at /etc/init/mongodb-instance.conf limit nofile 20000 20000 kill timeout 300 # wait 300s between SIGTERM and SIGKILL. stop on runlevel [06] instance $CONFIG script if [ -f "$CONFIG" ] then pidfile="/var/run/mongodb/`basename $CONFIG .conf`.pid" start-stop-daemon --pidfile "$pidfile" --start --quiet --chuid mongodb --exec /usr/bin/mongod -- --config "$CONFIG" fi end script post-stop script if [ -f "$CONFIG" ] then pidfile="/var/run/mongodb/`basename $CONFIG .conf`.pid" rm -f "$pidfile" fi end script |