http:// qmail.jms1.net / courier-daemontools.html

Running Courier-IMAP under daemontools

I use a package called Courier-IMAP on my servers to allow my users to access their mailboxes using the IMAP-SSL and POP3-SSL protocols.

I also use a system called daemontools to run most of the services on my servers, including the IMAP-SSL and POP3-SSL services of Courier-IMAP.

When I set it up the first time, I couldn't find any directions on how to make the Courier-IMAP services run under daemontools, so I cobbled together my own scripts to make it happen.

A recent post on the Courier-IMAP mailing list asks how to set this up. Because somebody asked on the mailing list, I'm assuming there is no other set of directions for this on the Internet yet, so I created this web page in the hope that others will find the information useful.


Setting up the service directories

Before you continue, make sure the daemontools "svscan" process is running, and that Courier-IMAP is installed. Normally Courier-IMAP installs itself to the directory /usr/lib/courier-imap, but if you have compiled it differently or installed it from a binary package, this directory may be different. In this case, you will need to adjust the "prefix=", "exec_prefix=", "bindir=", and "libexecdir=" lines of the "run" scripts below.

Choose a location where you want the physical service directories. I usually use "/usr/lib/courier-imap/supervise" and suggest you do the same, but make sure you do not create the physical directories under /service.

Start by creating the top-level directory which will contain the service directories.

# mkdir /usr/lib/courier-imap/supervise
# cd /usr/lib/courier-imap/supervise

Then create the actual service directories. You will need to create a separate service directory for each service (IMAP, IMAP-SSL, POP3, POP3-SSL) you wish to run. I personally run IMAP (on 127.0.0.1), IMAP-SSL, POP3-SSL, but the example will show all four services. Simply skip the lines pertaining to any services you don't want/need to run. (These commands assume you are still in the top-level service container directory.)

# mkdir imap imap/log
# mkdir imapssl imapssl/log
# mkdir pop3 pop3/log
# mkdir pop3ssl pop3ssl/log

Once you have created the directories, you need to install the "run" scripts for each one. These links point to text files which contain the scripts. Each script that you use should be called "run", and be placed in the correct directory.

File: service-imap-run
Size: 1,792 bytes
Date: 2008-05-08 16:58:41 +0000
MD5: 4dda3b3a40881855744858623b02f6fb
SHA-1: 366f7ed15754acd1b2c5185b2066cf09d6ed5e7c
RIPEMD-160: eeb48a620221f774e83c9c0727e69c20f537a529
PGP Signature: service-imap-run.asc
File: service-imapssl-run
Size: 2,009 bytes
Date: 2008-05-08 17:02:32 +0000
MD5: d9a7b90bafa3187c039ca66e67498c86
SHA-1: 3ec0571daa4fbd6c151f751e6f13beabaff6eda5
RIPEMD-160: 6aa5b85821cd1574b33fc3a01a3e8e7709946d10
PGP Signature: service-imapssl-run.asc
File: service-pop3-run
Size: 1,784 bytes
Date: 2008-05-08 17:03:41 +0000
MD5: e5da55c2f06f08f9a23d9cb87e115e87
SHA-1: e9eaeeba8e5b3cd70cb8b6e3ddced6e9f6f3f9d6
RIPEMD-160: a6ce7f5e5d9a49e0f41023cbe92450a6d2c9eaef
PGP Signature: service-pop3-run.asc
File: service-pop3ssl-run
Size: 1,884 bytes
Date: 2008-05-08 17:05:05 +0000
MD5: 5353b0588f23c6e8e4428ff4d521bdf6
SHA-1: 7fb84291b57695c58929b77c9e8dba5fb17f049f
RIPEMD-160: 38daf9946610864ae2e36bd11d39471e6f0f8ccf
PGP Signature: service-pop3ssl-run.asc

The service-any-log-run script can be used as /service/___/log/run for any of these services.

File: service-any-log-run
Size: 1,845 bytes
Date: 2006-08-11 22:48:48 +0000
MD5: 54a2d0a1d1ec77e7c737f5b65a9d876a
SHA-1: f7d6e683bcba52ebc3d8104201d43c49e2e64c94
RIPEMD-160: 501241a75dbe44121921582a10662ef926ffa32f
PGP Signature: service-any-log-run.asc

Before using these scripts, you should check them to make sure they will work on your system. The IP addresses and ports are configured using the same /usr/lib/courier-imap/etc/* files that you would use to configure the servers if they were running under rc files. However, you can override those values by uncommenting the indicated lines in these scripts.

Note: if you use ADDRESS=0, the resulting server will try to listen on that port number (usually 143 or 993) for EVERY IP ADDRESS ON THE SYSTEM. If any other program (such as another instance of the service) is listening on a specific IP with the same port, the ADDRESS=0 server will refuse to start... and if the ADDRESS=0 service is already running, the other one (with the specific IP) will refuse to start.

If you have special needs, for example a totally non-secured IMAP server on 127.0.0.1 port 143 for a webmail server, but a TLS-only server (or no server) on the ethernet's port 143, neither of the servers should be configured with ADDRESS=0. I've found that it's generally a bad idea to have services running on 0.0.0.0 anyway, except in very specific cases.

The next step is to set the permissions correctly. All of the "run" scripts need to be executable. In addition, the primary service directories need to have the "sticky" bit set on them. The sticky bit on a directory means that files contained in the directory may only be deleted by their owner (or root), even if the other permissions on the directory would permit the file to be deleted. This is normally used with the /tmp directory, where every user has full read/write access, to prevent one user from deleting another user's files (which would be a bad thing.)

Again, the following commands assume you are in the top-level service container directory (i.e. /usr/lib/courier-imap/supervise).

# chmod +x */run */log/run
# chmod -R go=u-w .
# chmod +t *


Activating the Services

Once the directories are set up, you need to make them start running. This is done by creating a symbolic link from /service/(whatever) to the physical directory where the service lives. The "svscan" program checks /service every five seconds, and when it sees a new directory (or symbolic link) there, it starts a "supervise" process for that directory. In addition, if the directory has the sticky bit set and a child directory called "log", it starts a "supervise" process for the "log" child directory and sets up a pipe between the two processes (so that the main process's logs end up being sent to the log process.)

The "supervise" program works by running the "run" script inside of whatever directory it's watching. If that child process (either the "run" script itself, or whatever process it runs using "exec") stops, it starts it back up by running the "run" script again.

The following commands will create the symbolic links needed to start the IMAP-SSL and POP3-SSL services (the ones I run.) If you need to run others, use the same command with the directory name for the service you're setting up.

Note: you do need to specify the full physical directory for each service. Simply typing the name and assuming it will find the rest because you're sitting in the top-level service container directory won't work for this command.

# ln -s /usr/lib/courier-imap/supervise/imapssl /service/
# ln -s /usr/lib/courier-imap/supervise/pop3ssl /service/

After running these commands, wait ten seconds (to give them time to start) and then run the "svstat" command to see what's running:

# svstat /service/* /service/*/log
/service/dnscache: up (pid 693) 123863 seconds
/service/dnspoison: up (pid 707) 123863 seconds
/service/imapssl: up (pid 3359) 6 seconds
/service/pop3ssl: up (pid 3362) 6 seconds

/service/qmail: up (pid 719) 123863 seconds
/service/smtp: up (pid 732) 123863 seconds
/service/dnscache/log: up (pid 694) 123863 seconds
/service/dnspoison/log: up (pid 708) 123863 seconds
/service/imapssl/log: up (pid 3360) 6 seconds
/service/pop3ssl/log: up (pid 3363) 6 seconds

/service/qmail/log: up (pid 721) 123863 seconds
/service/smtp/log: up (pid 733) 123862 seconds

As long as the new services show "up" with a timer of more than one second, the services are running correctly. If the timer on a service is 0 or 1 second, then wait about five seconds and run the same command- it should now be higher than 1 second. If it's still 0 or 1, then that service is having a problem and you need to fix it (i.e. keep reading.)


Troubleshooting

If you run into a problem with the services starting, there are a few places to check for error messages, which may or may not help.

As long as the "log" service starts correctly (it's rare for a "log" service to not start up- if this happens it's usually because of a mangled "multilog" command line) you will find a directory called "main" inside of the "log" directory, and it should contain a file called "current". This "log/main/current" file is the live log file being generated by the primary service. If it contains any data, the messages at the end of the file may provide a clue as to why the service isn't starting correctly.

The other place to look is the "readproctitle" process. This is a process (part of daemontools) which is always running in the background, and when you look at it (as part of a "ps" listing, for example) it will show you the last 400 bytes of any error messages that "svscan" may have encountered while trying to start the services. The messages you see here may prove helpful in finding the source of your problems.