Setup roundcube email MUA for webmail.

Setup MTA and MDA before configuration. See Setup.



Docker Creation

Configure the mail server before starting the docker container. See Setup.

  • Docker container should be run in an isolated network given the sensitive and exposed nature of the data and service.

  • Proxy will forward traffic to the container, so no ports need to be exposed.

Docker Compose
  image: roundcube/roundcubemail:latest-apache
  restart: "unless-stopped"
    driver: syslog
      tag: roundcube
    - "ROUNDCUBEMAIL_PLUGINS=archive,zipdownload"
    - "/data/mail/roundcube/config:/var/www/html/config"
    - "/data/mail/roundcube/db:/var/roundcube/db"


Use the explicit Common Name (FQDN) for host URI. PHP requires certificate validation by default now; and should match the explicit FQDN on the certificate that the mail server uses.


ROUNDCUBEMAIL_UPLOAD_MAX_FILE_SIZE should match the max file size defined on the mail server POSTFIX_MESSAGE_SIZE_LIMIT. See Docker Creation.


See roundcube configuration for configuration guide. See for defaults.

Reverse Proxy Setup

Allows you to isolate your containers as well as wrap connections in SSL. See NGINX for more details. See Setup Base Proxy Control for basic proxy configuration.

Using Subdomains

0644 root root nginx/conf.d/reverse-proxy.conf
server {
  listen       443 ssl http2;
  server_name  roundcube.{DOMAIN} roundcube;

  location / {
    proxy_pass http://roundcube;
    include    /etc/nginx/conf.d/proxy-control.conf;

Using Subpaths

0644 root root nginx/conf.d/reverse-proxy.conf
server {
  location /roundcube/ {
    proxy_pass http://roundcube;
    include    /etc/nginx/conf.d/proxy-control.conf;

Postgres Backend

Postgres may be used to store roundcube data in a centralized location. This assumes that Postgresql is already configured, with an empty database for roundcube to use (see Creating A Database).

Import the Roundcube DB schema.
psql -U roundcube -f SQL/postgres.initial.sql roundcube


The roundcube DB schema is defined in the roundcube respository.

Docker Compose Add Postgres Network.
    external: True
  image: roundcube/roundcubemail:latest-apache
    - db
0600 roundcube roundcube /var/www/html/config/
$config[‘db_dsnw’] = ‘pgsql://{USER}:{PASS}@{HOST}/{DB}';

fail2ban Setup

Enable fail2ban for MTA and MDA services.

Use fail2ban for Docker for the base fail2ban service setup.

Add read-only syslog logs to Docker Compose (f2b-docker)
    - /var/log/syslog:/var/log/syslog:ro

Enable logging of sucessful user logins.

0644 root root /data/mail/roundcube/config/
  $config['log_logins'] = true

Roundcube Filters

Custom filter to match roundcube log messages in syslog, with roundcube operating behind a proxy.

0644 root root /data/filter.d/mail-roundcube.conf
# Fail2Ban configuration file for docker roundcube web server behind proxy.


before = common.conf


prefregex = ^\s*(\[\])?(%(__hostname)s\s*(?:roundcube(?:\[(\d*)\])?:)?\s*.*(<[\w]+>)? IMAP Error)?: <F-CONTENT>.+</F-CONTENT>$

failregex = ^(?:FAILED login|Login failed) for <F-USER>.*</F-USER> against .*X-Forwarded-For: <HOST>.*$
            ^(?:<[\w]+> )?Failed login for <F-USER>.*</F-USER> against .*X-Forwarded-For: <HOST> .*$

ignoreregex =

journalmatch = SYSLOG_IDENTIFIER=roundcube

Roundcube Jails

0644 root root /data/jail.d/roundcube.conf
enabled  = true
port     = http,https
filter   = mail-roundcube
logpath  = /var/log/syslog
bantime  = -1
findtime = 86400
maxretry = 3
  • Restart f2b-docker.