diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index c71aa8dd..bcdc7975 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -38,7 +38,6 @@ RUN set -eu \ && rm -rf /var/lib/apt/lists ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.5.1/roundcubemail-1.5.1-complete.tar.gz - ENV CARDDAV_URL https://github.com/mstilkerich/rcmcarddav/releases/download/v4.3.0/carddav-v4.3.0.tar.gz RUN set -eu \ @@ -58,10 +57,10 @@ RUN set -eu \ && a2enmod rewrite deflate expires headers \ && echo date.timezone=${TZ} > /usr/local/etc/php/conf.d/timezone.ini -COPY php.ini /php.ini -COPY config.inc.php /var/www/html/config/ COPY mailu.php /var/www/html/plugins/mailu/mailu.php -COPY start.py /start.py +COPY php.ini / +COPY config.inc.php / +COPY start.py / EXPOSE 80/tcp VOLUME ["/data"] diff --git a/webmails/roundcube/config.inc.php b/webmails/roundcube/config.inc.php index 99f147fc..67a8065d 100644 --- a/webmails/roundcube/config.inc.php +++ b/webmails/roundcube/config.inc.php @@ -3,46 +3,29 @@ $config = array(); // Generals -$config['db_dsnw'] = getenv('DB_DSNW');; +$config['db_dsnw'] = '{{ DB_DSNW }}'; $config['temp_dir'] = '/tmp/'; -$config['des_key'] = getenv('SECRET_KEY') ? getenv('SECRET_KEY') : trim(file_get_contents(getenv('SECRET_KEY_FILE'))); +$config['des_key'] = '{{ SECRET_KEY }}'; $config['cipher_method'] = 'AES-256-CBC'; $config['identities_level'] = 0; $config['reply_all_mode'] = 1; - -// List of active plugins (in plugins/ directory) -$config['plugins'] = array( - 'archive', - 'zipdownload', - 'markasjunk', - 'managesieve', - 'enigma', - 'carddav' -); - -$front = getenv('FRONT_ADDRESS') ? getenv('FRONT_ADDRESS') : 'front'; -$imap = getenv('IMAP_ADDRESS') ? getenv('IMAP_ADDRESS') : 'imap'; +$config['log_driver'] = 'stdout'; +$config['zipdownload_selection'] = true; +$config['enable_spellcheck'] = true; +$config['spellcheck_engine'] = 'pspell'; // Mail servers -$config['default_host'] = $front; +$config['default_host'] = '{{ FRONT_ADDRESS or "front" }}'; $config['default_port'] = 10143; -$config['smtp_server'] = $front; +$config['smtp_server'] = '{{ FRONT_ADDRESS or "front" }}'; $config['smtp_port'] = 10025; $config['smtp_user'] = '%u'; $config['smtp_pass'] = '%p'; // Sieve script management -$config['managesieve_host'] = $imap; +$config['managesieve_host'] = '{{ IMAP_ADDRESS or "imap" }}'; $config['managesieve_usetls'] = false; -// Customization settings -if (filter_var(getenv('ADMIN'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { - $config['support_url'] = getenv('WEB_ADMIN') ? '../..' . getenv('WEB_ADMIN') : ''; -} -$config['product_name'] = 'Mailu Webmail'; -array_push($config['plugins'], 'mailu'); -$config['sso_logout_url'] = '/sso/logout'; - // We access the IMAP and SMTP servers locally with internal names, SSL // will obviously fail but this sounds better than allowing insecure login // from the outter world @@ -56,11 +39,22 @@ $config['imap_conn_options'] = $ssl_no_check; $config['smtp_conn_options'] = $ssl_no_check; $config['managesieve_conn_options'] = $ssl_no_check; +// roundcube customization +$config['product_name'] = 'Mailu Webmail'; +{%- if ADMIN and WEB_ADMIN %} +$config['support_url'] = '../..{{ WEB_ADMIN }}'; +{%- endif %} +$config['plugins'] = array({{ PLUGINS }}); + // skin name: folder from skins/ $config['skin'] = 'elastic'; -// Enigma gpg plugin +// configure mailu sso plugin +$config['sso_logout_url'] = '/sso/logout'; + +// configure enigma gpg plugin $config['enigma_pgp_homedir'] = '/data/gpg'; // Set From header for DKIM signed message delivery reports $config['mdn_use_from'] = true; + diff --git a/webmails/roundcube/healthcheck.sh b/webmails/roundcube/healthcheck.sh new file mode 100755 index 00000000..97ecf745 --- /dev/null +++ b/webmails/roundcube/healthcheck.sh @@ -0,0 +1,2 @@ +#!/bin/sh +SCRIPT_NAME=/ping SCRIPT_FILENAME=/ping REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000 2>/dev/null | grep -qFx pong diff --git a/webmails/roundcube/start.py b/webmails/roundcube/start.py index 64147681..2b217539 100755 --- a/webmails/roundcube/start.py +++ b/webmails/roundcube/start.py @@ -1,67 +1,102 @@ #!/usr/bin/python3 import os -import logging as log +import logging import sys from socrate import conf import subprocess +import hmac -log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING")) +env = os.environ -os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT")) * 0.66 / 1048576)) +logging.basicConfig(stream=sys.stderr, level=env.get("LOG_LEVEL", "WARNING")) -db_flavor = os.environ.get("ROUNDCUBE_DB_FLAVOR", "sqlite") +# jinja context +context = {} +context.update(env) + +context["MAX_FILESIZE"] = str(int(int(env.get("MESSAGE_SIZE_LIMIT", "50000000")) * 0.66 / 1048576)) + +db_flavor = env.get("ROUNDCUBE_DB_FLAVOR", "sqlite") if db_flavor == "sqlite": - os.environ["DB_DSNW"] = "sqlite:////data/roundcube.db" + context["DB_DSNW"] = "sqlite:////data/roundcube.db" elif db_flavor == "mysql": - os.environ["DB_DSNW"] = "mysql://%s:%s@%s/%s" % ( - os.environ.get("ROUNDCUBE_DB_USER", "roundcube"), - os.environ.get("ROUNDCUBE_DB_PW"), - os.environ.get("ROUNDCUBE_DB_HOST", "database"), - os.environ.get("ROUNDCUBE_DB_NAME", "roundcube") + context["DB_DSNW"] = "mysql://%s:%s@%s/%s" % ( + env.get("ROUNDCUBE_DB_USER", "roundcube"), + env.get("ROUNDCUBE_DB_PW"), + env.get("ROUNDCUBE_DB_HOST", "database"), + env.get("ROUNDCUBE_DB_NAME", "roundcube") ) elif db_flavor == "postgresql": - os.environ["DB_DSNW"] = "pgsql://%s:%s@%s/%s" % ( - os.environ.get("ROUNDCUBE_DB_USER", "roundcube"), - os.environ.get("ROUNDCUBE_DB_PW"), - os.environ.get("ROUNDCUBE_DB_HOST", "database"), - os.environ.get("ROUNDCUBE_DB_NAME", "roundcube") + context["DB_DSNW"] = "pgsql://%s:%s@%s/%s" % ( + env.get("ROUNDCUBE_DB_USER", "roundcube"), + env.get("ROUNDCUBE_DB_PW"), + env.get("ROUNDCUBE_DB_HOST", "database"), + env.get("ROUNDCUBE_DB_NAME", "roundcube") ) else: - print("Unknown ROUNDCUBE_DB_FLAVOR: %s", db_flavor) + print(f"Unknown ROUNDCUBE_DB_FLAVOR: {db_flavor}", file=sys.stderr) exit(1) -conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/roundcube.ini") +# derive roundcube secret key +secret_key = env.get("SECRET_KEY") +if not secret_key: + try: + secret_key = open(env.get("SECRET_KEY_FILE"), "r").read().strip() + except Exception as exc: + print(f"Can't read SECRET_KEY from file: {exc}", file=sys.stderr) + exit(2) -# Create dirs, setup permissions +context['SECRET_KEY'] = hmac.new(bytearray(secret_key, 'utf-8'), bytearray('ROUNDCUBE_KEY', 'utf-8'), 'sha256').hexdigest() + +# roundcube plugins +# (using "dict" because it is ordered and "set" is not) +plugins = dict((p, None) for p in env.get("ROUNCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/plugins", p))) +if plugins: + plugins["mailu"] = None +else: + plugins = dict((k, None) for k in ["archive", "zipdownload", "markasjunk", "managesieve", "enigma", "carddav", "mailu"]) + +context["PLUGINS"] = ",".join(f"'{p}'" for p in plugins) + +# create config files +conf.jinja("/php.ini", context, "/usr/local/etc/php/conf.d/roundcube.ini") +conf.jinja("/config.inc.php", context, "/var/www/html/config/config.inc.php") + +# create dirs os.system("mkdir -p /data/gpg") +print("Initializing database") try: - print("Initializing database") result = subprocess.check_output(["/var/www/html/bin/initdb.sh", "--dir", "/var/www/html/SQL"], stderr=subprocess.STDOUT) print(result.decode()) -except subprocess.CalledProcessError as e: - if "already exists" in e.stdout.decode(): +except subprocess.CalledProcessError as exc: + err = exc.stdout.decode() + if "already exists" in err: print("Already initialzed") else: - print(e.stdout.decode()) - quit(1) + print(err) + exit(3) +print("Upgrading database") try: - print("Upgrading database") subprocess.check_call(["/var/www/html/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT) -except subprocess.CalledProcessError as e: - quit(1) +except subprocess.CalledProcessError as exc: + exit(4) else: + print("Cleaning database") try: - print("Cleaning database") subprocess.check_call(["/var/www/html/bin/cleandb.sh"], stderr=subprocess.STDOUT) - except subprocess.CalledProcessError as e: - quit(1) + except subprocess.CalledProcessError as exc: + exit(5) -# Setup database permissions +# setup permissions os.system("chown -R www-data:www-data /data") -# Run apache -os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"]) +# clean env +[env.pop(key, None) for key in env.keys() if key == "SECRET_KEY" or key.startswith("ROUNDCUBE_")] + +# run apache +os.execve("/usr/local/bin/apache2-foreground", ["apache2-foreground"], env) +