Unix is an OS built around a worse is better philosophy. Part of that philosophy is defining things through convention. This has many advantages. One is thats its really easy to write a program that can run in both the console and as a daemon.
The mongo server, mongod, is a perfect example of this. If you run mongod in the console, it spews all its output to stdout. This is great for development and testing. However, if you want to run mongod all the time, its very simple to run it from an init script.
On the windows side of things, its more complicated. In windows, daemons run as services, except apparently if you are using an Azure instance. Services operate separately from interactive processes. Actually, thats not entirely true. You can have a service that interacts with the windows gui if you want to. As I said, its complicated.
In order for a windows program to operate as a service, you have to make certain API calls. Its actually not that hard in its most basic form, and there are well established patterns for doing it.
Furthermore, there is actually a wrapper program in the windows resource kit tool srvany.exe. It will allow you to turn almost any console program into a windows service. However, it is not an ideal solution. Luckily a programmer by the name of Alan Wright added proper windows service support to mongod. It was a well implemented service wrapper and I have made good use of it. I have also contributed some modifications to it that 10gen graciously accepted into their repo. The result is a really clean, but powerful service implementation built into mongod. I shall now demonstrate the power of this fully armed and operational death. . . I mean demonstrate the power of mongod’s windows service support.
Before we Begin
First, You are going to want to download the latest stable version of mongo. As of this writing that is mongo 1.6.3. Since mongo is evolving so rapidly, some of the more advanced features related to windows service support, not covered in this article, are only available in the unstable 1.7 series. Things move fast on the bleeding edge.
Second, you want to make sure you have mongod installed in a sane location. My definition of sane location is pretty much anyplace outside of C:Documents and Settings or C:Users. This also means on a hard drive permanently attached to your system. Theres nothing wrong with running mongod off an external hard drive if its always plugged in. Just keep in mind you won’t be able to unplug it while mongo is running, and the service will fail to start up if you boot your system without the drive plugged in.
Third, you want to be able to run mongod from a command prompt using the same switches as you wish the service to use. Please note that you are required to use logging when running mongod as a windows service. In my case I will run mongod like this:
mongod --auth --logpath c:datalogmongo.log --logappend --bind_ip localhost
What I am doing here is not overwriting the log every time I start mongo, and only listening for local connections. If mongod is running on the same machine as your web server, this is a good idea. I am also running with authentication.
Finally you want to make sure your command prompt has administrative access to your computer. Mongod will not raise a UAC prompt and elevate its own privileges. However, there’s a ticket for that. So make sure your do all the following steps from a command prompt running as an administrator. Also, note that in a future article I will talk about running mongod as a service using an unprivileged user.
And now we install the service
So you’ve worked out your particular command line options, made your data andlog folders, etc, etc. Double check your mongo log to make sure there are no errors. Now we are ready to install mongod as a service. To do this we simply append –install to the command prompt. So our install command looks like:
mongod --auth --logpath c:datalogmongo.log --logappend --bind_ip localhost --install
That should output the following:
C:\Program Files\Microsoft SDKs\Windowsv7.1>mongod --auth --logpath c:datalogmongo.log --logappend --bind_ip localhost --install all output going to: c:datalogmongo.log Creating service MongoDB. Service creation successful. Service can be started from the command line via 'net start "MongoDB"'.
Now lets say to want to change the parameters. For example, you decide to run without authentication. If mongod is already installed as a service, and you want to change the command line parameters, then you have to use –reinstall instead of –install. So lets try that now:
C:\Program Files\Microsoft SDKs\Windowsv7.1>mongod --logpath c:datalogmongo.log --logappend --bind_ip localhost --reinstall all output going to: c:datalogmongo.log Deleting service MongoDB. Service deleted successfully. Creating service MongoDB. Service creation successful. Service can be started from the command line via 'net start "MongoDB"'.
So as you can see –reinstall removes the service and then installs it again. Pretty self explanatory.
Ok and finally we want to cleanup. To remove mongod as a service, we will use –remove. The output:
C:\Program Files\Microsoft SDKs\Windowsv7.1>mongod --remove Deleting service MongoDB. Service deleted successfully. Thu Sep 30 19:32:56 dbexit: Thu Sep 30 19:32:56 shutdown: going to close listening sockets... Thu Sep 30 19:32:56 shutdown: going to flush oplog... Thu Sep 30 19:32:56 shutdown: going to close sockets... Thu Sep 30 19:32:56 shutdown: waiting for fs preallocator... Thu Sep 30 19:32:56 shutdown: closing all files... Thu Sep 30 19:32:56 closeAllFiles() finished Thu Sep 30 19:32:56 dbexit: really exiting now
You will note that this command seems extra verbose. This is because messages that would normally be sent to the log are being sent to stdout.
Starting and Stopping the Service
There are several ways to start and stop a windows service. You can use the Service Control Manager or SCM of course. However, since we are on the command line already, we might as well use that. The command to start our mongo service is “net start mongodb.” Likewise, “net stop mingodb” stops our service. The service is configured to automatically startup at boot time, which is probably what you want. If not you can tune this behavior in the SCM.
This is only the tip of the mongo as a windows service iceberg. More options are available. I will be discussing them in depth in future articles.