Lightweight & fast webmail client

My main home server is a measly pentium II class machine running (now) on Debian Etch. Not the fastest machine but it works, uses little power and is cheap while setup from left-overs. Among other things it serves me my email when not at home using RoundCube Webmail. With the low-end hardware I am using it is key to keep it as fast and lightweight as possible. The server is behind a DSL connection at home so compression comes in handy as well.

I have tested a couple of different setups for this server but now have settled on Courier imapd, imap-proxy and Lighttpd with Php-fastcgi. For the article I assume we have a working imap server, it doesn’t necessarily has to be courier and doesn’t need to be on the same server as well, but over here it is. I have bound courier-imapd to localhost, and courier-imapd-ssl to the local network for using from my workstation. In this scenario there is no un-encrypted imap traffic over any cable. On a trusted network that would probably be fine (depending on preference or rules) but RoundCube does support imap over ssl.

For this setup I choose debian packaged software where I can as it saves me the compile time and keeping up-to-date is easy.

Normally, with php-based webmail clients a major overhead is opening and closing the imap connection to the user’s inbox on every read, both for the webserver and the mailserver. Imapproxy creates and keeps a connection for a configurable amount of time on behalf of the user logging in to the webmail client. To the webmail client it acts like a normal imap server but the overhead of reading the user’s entire mailbox is reduced.

# apt-get install imapproxy
# gedit /etc/imapproxy.conf
server_hostname localhost
listen_port 144 #or any other free port, remember I have courier bound to 143 already
server_port 143
enable_select_cache yes
# /etc/init.d/imapproxy restart

Now we need a webserver, I choose Lighttpd because it is lightweight and fast. On top of lighttpd I run php5 in fast CGI mode (as it prespawns php processes the setup overhead is gone). In lighttpd I enable SSL, compress and optionally userdir. RoundCube will need some kind of database backend, since the use is limited I choose sqlite because it uses files as a backend, saving me the memory for a postgres or mysql backend.
# apt-get install lighttpd php5-cgi php5-sqlite php5-mcrypt php5-gd

In Etch, the packaged 10-fastcgi.conf file is hardcoded for php4. Edit the ‘bin-path’ in /etc/lighttpd/conf-available/10-fastcgi.conf to /usr/bin/php-cgi:
### changed for php5
"bin-path" => "/usr/bin/php-cgi",

Now enable the modules, one by one:
# lighty-enable-mod
# lighty-enable-mod
###this last one is optional
# lighty-enable-mod

You will need a SSLcertificate in /etc/lighttpd/server.pem, a self-signed one is easily created:
$ cd /etc/lighttpd
# make-ssl-cert /usr/share/ssl-cert/ssleay.cnf server.pem

You should now get a welcome message on http://yourserver, on https://yourserver, and when you have a ~/public_html directory http://yourserver/~youruser should work as well.

Now get the latest stable RoundCube version (0.2 at time of writing), and have a quick look at the installation manual.

First, choose an installation directory, I use my own public_html for testing purposes (if you have enabled the module userdir) before. Extract the tar, rename or link it to something easier, setup sqlite and check access rights. The sqlite database should be readable and writable by the www-data user.
$ cd public_html
$ tar xzf ~/Downloads/roundcubemail-0.2-stable.tar.gz
$ mv roundcubemail-0.2-stable/ rc
$ cd rc
# chown www-data temp logs
# sudo -u www-data sqlite -init SQL/sqlite.initial.sql /var/tmp/rc.sqlite.db
CTRL-D to exit

Note: /var/tmp is NOT a good idea for production use!

Now it’s time to configure. Point your browser to http://yourserver/~user/rc/url-to-roundcube/installer/ to start the installation wizzard (yeh!).
You can now setup your RoundCube the way you wish to, this is later easily changable by editing the created configuration files.
The db configuration is a bit tricky, as it lists hostname, username and password textboxes even though the sqlite driver is selected. Keep them empty. After clicking ‘Create config’ copy the contents of the textareas or use the download links and edit
$rcmail_config['db_dsnw'] = 'sqlite:////var/tmp/rc.sqlite.db?mode=0646';

Now test it. If you are able to login and see your email you must delete the installer directory.

You could wonder why I don’t compile all software myself to push out those few last drops of performance. I feel that is a matter of preference. I feel 24 hours of compiling time isn’t worth it compared to using debian packages where I don’t have to track security issues myself, a dist-upgrade usually just works. The other optimizations as laid out in this article (proxying of imap connections and the smaller webserver, prespawned php processes etc) have much more impact.

ps: When I started writing this Debian Lenny was still “testing”, so there might be some small inconsistencies in config files.

ps2: some after-thoughts on getting to a more production-grade system.

  • It would be nice to keep the https and http document roots separate, you could do a redirect from http to https as a service to the customers.
  • By adding something to lighty’s 10-ssl.conf like
    alias.url += ( "/webmail/" => "/home/webmail/htdocs/rc/" )
    RoundCube is only visible via https in the webmail directory.

  • For production use a self-signed certificate is imho still ok, at least when fqdn matches and ttl is not too long.
  • When you have a /home/webmail directory that would be the obvious choice for storing the database file.
  • I wonder at which number of simultaneous clients it would start to make sense to use a ‘real’ dbms (postgres) instead of the flat files; I’d guess that might be quite a high number (> 25).
  • A separate outgoing queue on the webmail server itself with its smarthost set to your normal mailserver might speed up sending emails.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>