Multiple MongoDB Instances with Ubuntu’s Upstart

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:

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:

# 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:

# 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.

# 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/.

# 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/.

# 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
Find this content useful? Share it with your friends!