Webmail using Roundcube

This page deals with the installation of Roundcube as a web mail interface. Roundcube is the software that was also used in the previous versions of this guide. So if your users are used to it… just stay with it.

If my spare time allows it this guide will be extended by alternative mail clients like Horde, Rainloop and Nextcloud.


Start by installing the software packages:

apt install roundcube roundcube-plugins roundcube-plugins-extra roundcube-mysql

Roundcube stores user settings in the database. So you will get asked to set up database access:

Or course choose mysql when asked:

When asked for a password just press ENTER.

Configure Apache

To get Apache to serve the Roundcube application you need to edit the /etc/apache2/sites-available/webmail.example.org-https.conf file. I suggest you change the DocumentRoot line to:

DocumentRoot /var/lib/roundcube

Also add this line within the same VirtualHost section to add a couple of prepared security settings:

Include /etc/roundcube/apache.conf

And as usual Apache needs to be restarted after the configuration change:

systemctl restart apache2

Limit access to localhost

The main configuration file of Roundcube is located at /etc/roundcube/config.inc.php. Feel free to customize the file. However I suggest that you make these changes:

$config['default_host'] = 'tls://webmail.example.org';

If you do not set the default_host here then Roundcube will ask the user for the name of the mail server at login. We don’t want that.

Also for sending emails you should use the same submission port as other email clients use:

$config['smtp_server'] = 'tls://webmail.example.org';
$config['smtp_port'] = 587;

So now when your users enter https://webmail.example.org/ in their browser they will get the Roundcube webmail application. Voila. Webmail works.

Username == email address

Keep in mind that we are using the email address as the account name of the user. So when logging in please enter the email address as the user name. E.g. ‘john@example.org’ and password ‘summersun’.


Roundcube comes with various plugins that you can offer your users. I suggest to use at least these two:

  • password: Let the user change their access password.
  • managesieve: Let the user manage rules that apply to incoming email. They can move mails to specific folders automatically for example.

Again edit the /etc/roundcube/config.inc.php file and look for the plugins configuration. To enable my recommended plugins change it to:

$config['plugins'] = array(

password plugin

Plugins are configured through files located in the /etc/roundcube/plugins directory. Let’s begin with the password plugin. Edit the /etc/roundcube/plugins/password/config.inc.php file.

Oops, that file looks pretty empty. But it refers us to an example file at /usr/share/roundcube/plugins/password/config.inc.php.dist. There are many different methods to let users change their passwords. As we store that information in the SQL database that is the part we need to set up.

Remove the empty definition line of $config from your config.inc.php file. Let’s go through the required settings one by one:

  • $config['password_driver'] = 'sql';
    Simple. Use SQL as a backend.
  • $config['password_minimum_length'] = 12;
    Allow no passwords shorter than 12 characters. I consider longer passwords more secure than short passwords with weird characters. You can even choose a larger minimum.
  • $config['password_force_save'] = true;
    This will overwrite the password in the database even if it hasn’t changed. It helps us improve the strength of the password hash even if the user chooses to keep his old password.
  • $config['password_algorithm'] = 'dovecot';
    Make Roundcube use the below dovecot-based settings.
  • $config['password_dovecotpw'] = '/usr/bin/doveadm pw -s BLF-CRYPT';
    The command to create a hash for a new password that the user entered.
  • $config['password_dovecotpw_method'] = 'BLF-CRYPT';
    Add a prefix to the password hash that explicitly designates it as a bcrypt hash. That makes it easy if in the future we want to use other hashing algorithms.
  • $config['password_dovecotpw_with_method'] = true;
    Enable the above setting.
  • $config['password_db_dsn'] = 'mysql://mailadmin:gefk6lA2brMOeb8eR5WYaMEdKDQfnF@localhost/mailserver';
    Connection information for the local database. Use your own password for the mailadmin database user here. We cannot use the restricted mailserver user because we have to actually change data in the database.
  • $config['password_query'] = "UPDATE virtual_users SET password=%D WHERE email=%u";
    The SQL query that is run to write the new password hash into the database. %D is a placeholder for the new password hash. And %u is obviously the email address.

Try it. Log into Roundcube as ‘john@example.org’ with password ‘summersun’. Go to the Settings. Choose Password. Enter a new password twice. You should get a success message at the bottom right (yeah, it’s a bit hidden). Now logout and login with the new password. Does it work? Great.

sieve plugin

Sieve is used for server-side rules. Dovecot executes these rules every time a new email comes in. Of course every mailbox can have its own rules. To manage sieve rules Dovecot offers the managesieve interface that you enabled earlier. So we just need to tell Roundcube how to reach it.

The configuration file for Roundcube’s managesieve plugin is found at /etc/roundcube/plugins/managesieve/config.inc.php. Edit the file and again remove the empty or comment the $config line. You can again find all possible configuration options in the /usr/share/roundcube/plugins/managesieve/config.inc.php.dist file.

This time just one setting is required to tell Roundcube which server to talk to:

$config['managesieve_host'] = 'localhost';

Sieve rules are stored in a special syntax on the server. This is an example that moves all incoming emails to the test folder if it contains “test” in the mail’s subject line:

require ["fileinto"];
if header :contains "subject" "test"
  fileinto "INBOX.test";

But hardly anyone manages rules like that. Roundcube’s rule editor is more user-friendly.

Try adding a sieve rule for john@example.org in Roundcube. If it works you will find the machine-readable sieve code at /var/vmail/example.org/john/sieve/roundcube.sieve.

22 thoughts on “Webmail using Roundcube

  • 2019-12-30 at 21:25

    For completeness, a note to restart Apache should be added – otherwise the changed DocumentRoot directive is not in effect πŸ™‚

    • 2019-12-31 at 11:50

      Indeed. Thanks. Added.

  • 2020-01-02 at 21:38

    …just in case you are struggling with the same “Could not save new password. Encryption function missing.” error as I did:

    Find the “disable_functions” statement in your php.ini file and check whether the “proc_open” function is listed there. In my case it was. As a result, the subprocess, which is supposed to calculate hash of the new password, could not be spawned properly. The “[…] proc_open() has been disabled for security reasons […]” message in /var/log/roundcube/errors pointed me in that direction.

    • 2020-04-09 at 14:37

      I am keep getting this error “Could not save new password. Encryption function missing” even though disable_functions are clear (everything is allowed). What’s wrong with this plugin?

      • 2020-04-12 at 15:33

        After few minutes of debugging it turned out to be a problem with permissions for /etc/dovecot/conf.d/90-sieve.conf. Update password function is executed as www-data user which had no permissions to read above file.

        • 2020-04-14 at 21:20

          Add the same issue, in fact several files in dovecot conf.d were not accessible by www-data user.
          Troubleshooted using :
          # su – www-data -s /bin/bash
          # doveadm pw -s BLF-CRYPT -p secret
          this produced 2 errors :
          1. doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/10-tcpwrapper.conf line 0: Couldn’t open include file /etc/dovecot/conf.d/10-ssl.conf: Permission denied
          2. Error: net_connect_unix(/var/run/dovecot/stats-writer) failed: Permission denied

          both can be solved by setting correct perms

          • 2020-04-14 at 21:21

            s/Add/Had/ πŸ™‚

          • 2020-04-19 at 21:04

            I also think that definition in cfg /usr/share/roundcube/plugins/password/password.php file is incorrect:

            $config[‘password_dovecotpw’] = ‘/usr/bin/doveadm pw -s BLF-CRYPT’;

            because by looking at /usr/share/roundcube/plugins/password/password.php file we see following section:
            case ‘dovecot’:
            $pipe = proc_open(“$dovecotpw -s ‘$method'”, $spec, $pipes);

            But it somehow works πŸ˜‰ Weird.

          • 2020-04-19 at 21:10

            Oh, I meant

            I also think that definition in cfg /etc/roundcube/plugins/password/config.inc.php file is incorrect:

  • 2020-01-04 at 04:37

    In case you edit the php files and the screen comes up empty, take a look in /var/log/apache2/error.log – it always show some clue. My mistake was look into /var/lib/roundcube/logs

  • 2020-01-06 at 00:03

    Hello Christoph,

    Thank you for the great tutorials for many years.

    You wrote to set:
    $config[‘smtp_host’] = ‘tls://webmail.example.org’;
    I don’t find that in my roundcube config. I did find:
    $config[‘smtp_server’] = ‘localhost’;

    I guess it is probably the same but maybe you can confirm that?

    • 2020-01-07 at 08:09

      Oops, I mixed up default_host and smtp_server. Thanks for spotting.

  • 2020-01-06 at 03:25

    $config[‘smtp_server’]=’tls://webmail.example.org’ works for me.

  • 2020-01-12 at 22:41

    The test-user is ‘john@example.org’, not ‘john@example.com’.

    • 2020-01-12 at 23:26

      Yes – at this moment I also stopped and looked for where I have something wrong entered πŸ™‚
      Great tutorial – many thanks!
      I have several mail servers on Deban without mysql but now I am happy to read and set up a new server. Many thanks for your work.

    • 2020-01-14 at 12:03

      Ouch. Thanks. Fixed.

  • 2020-05-11 at 11:50

    Just a remark… My debian installer enabled mpm_event by default for apache2, which is not compatible with PHP. So, had to:

    a2dismod mpm_event
    a2enmod mpm_prefork
    a2enmod mpm_php7.3
    systemctl restart apache2

  • 2020-05-11 at 12:03

    Also, I think www-data needs read privileges for the config.inc.php and debian-db.php file. So maybe:

    chgrp www-data config.inc.php
    chgrp www-data debian-db.php
    chmod g+x config.inc.php
    chmod g+x debian-db.php

  • 2020-05-15 at 13:14

    Apologies, for nit-picking yet again.

    Under ‘Limiting access to localhost’ both the variables are set to point to the external, actual domain name.

    I am just wondering, whether I can get away with jus setting ‘tls://localhost’, making the multi-domain hosting yet one bit easier.

    • 2020-05-15 at 13:16

      And, yes, in fact, then we don’t even need TLS technically, but I reckon, otherwise the auth might not be triggered.

  • 2020-06-05 at 00:42

    Just for the record: I’ve tried it, and it works fine with just plain ‘localhost’ for both ‘default_host’ and ‘smtp_server’. Also cross-checked with the previous tutorials, and those suggest just simply ‘localhost’.

    • 2020-06-05 at 09:16

      Correction: IMAP will work, but sending will fail, as we only accept AUTH on TLS.


Leave a Reply to ct tang Cancel reply

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