Upgrade Snappymail to 2.21 and merge the webmail containers

main
Florent Daigniere 2 years ago
parent 8a90f83bd0
commit dc9e2a3e70

@ -340,7 +340,7 @@ jobs:
strategy:
fail-fast: false
matrix:
target: ["core", "fetchmail", "filters", "snappymail", "roundcube", "webdav"]
target: ["core", "fetchmail", "filters", "webmail", "webdav"]
time: ["2"]
include:
- target: "filters"
@ -394,7 +394,7 @@ jobs:
strategy:
fail-fast: false
matrix:
target: ["setup", "docs", "fetchmail", "roundcube", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx", "snappymail"]
target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx"]
steps:
- uses: actions/checkout@v3
- name: Retrieve global variables
@ -439,7 +439,7 @@ jobs:
strategy:
fail-fast: false
matrix:
target: ["setup", "docs", "fetchmail", "roundcube", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx", "snappymail"]
target: ["setup", "docs", "fetchmail", "webmail", "admin", "traefik-certdumper", "radicale", "clamav", "rspamd", "postfix", "dovecot", "unbound", "nginx"]
steps:
- uses: actions/checkout@v3
- name: Retrieve global variables

@ -168,7 +168,7 @@ services:
# Webmail
{% if webmail_type != 'none' %}
webmail:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}{{ webmail_type }}:${MAILU_VERSION:-{{ version }}}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}webmail:${MAILU_VERSION:-{{ version }}}
restart: always
env_file: {{ env }}
volumes:

@ -119,7 +119,7 @@ services:
{% if webmail_type != 'none' %}
webmail:
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}{{ webmail_type }}:${MAILU_VERSION:-{{ version }}}
image: ${DOCKER_ORG:-mailu}/${DOCKER_PREFIX:-}webmail:${MAILU_VERSION:-{{ version }}}
env_file: {{ env }}
volumes:
- "{{ root }}/webmail:/data"

@ -36,8 +36,7 @@ group "default" {
"imap",
"smtp",
"snappymail",
"roundcube",
"webmail",
"antivirus",
"fetchmail",
@ -169,24 +168,15 @@ target "smtp" {
}
# -----------------------------------------------------------------------------------------
# Webmail images
# Webmail image
# -----------------------------------------------------------------------------------------
target "snappymail" {
target "webmail" {
inherits = ["defaults"]
context = "webmails/snappymail/"
context = "webmails/"
contexts = {
base = "target:base"
}
tags = tag("snappymail")
}
target "roundcube" {
inherits = ["defaults"]
context = "webmails/roundcube/"
contexts = {
base = "target:base"
}
tags = tag("roundcube")
tags = tag("webmail")
}
# -----------------------------------------------------------------------------------------

@ -0,0 +1 @@
Upgrade Snappymail to 2.21 and merge the webmail containers

@ -1,6 +1,5 @@
# syntax=docker/dockerfile-upstream:1.4.3
#roundcube image
FROM base
ARG VERSION
@ -19,6 +18,7 @@ RUN set -euxo pipefail \
; mkdir -p /run/nginx \
; mkdir -p /conf
# roundcube
ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.5.3/roundcubemail-1.5.3-complete.tar.gz
ENV CARDDAV_URL https://github.com/mstilkerich/rcmcarddav/releases/download/v4.4.3/carddav-v4.4.3.tar.gz
@ -26,26 +26,44 @@ RUN set -euxo pipefail \
; cd /var/www \
; curl -sL ${ROUNDCUBE_URL} | tar xz \
; curl -sL ${CARDDAV_URL} | tar xz \
; mv roundcubemail-* webmail \
; mkdir -p /var/www/webmail/config \
; mv carddav webmail/plugins/ \
; cd webmail \
; mv roundcubemail-* roundcube \
; mkdir -p /var/www/roundcube/config \
; mv carddav roundcube/plugins/ \
; cd roundcube \
; rm -rf CHANGELOG.md SECURITY.md INSTALL LICENSE README.md UPGRADING composer.json-dist installer composer.* \
; ln -sf index.php /var/www/webmail/sso.php \
; chmod -R u+w,a+rX /var/www/webmail \
; chown -R nginx:nginx /var/www/webmail \
; ln -sf index.php /var/www/roundcube/sso.php \
; chmod -R u+w,a+rX /var/www/roundcube \
; chown -R nginx:nginx /var/www/roundcube \
; rm -rf plugins/{autologon,example_addressbook,http_authentication,krb_authentication,new_user_identity,password,redundant_attachments,squirrelmail_usercopy,userinfo,virtuser_file,virtuser_query}
COPY roundcube/config/config.inc.php /conf/
COPY roundcube/login/mailu.php /var/www/roundcube/plugins/mailu/
COPY roundcube/config/config.inc.carddav.php /var/www/roundcube/plugins/carddav/config.inc.php
# nginx / PHP config files
COPY config/nginx-roundcube.conf /conf/
COPY config/php-roundcube.conf /etc/php81/php-fpm.d/roundcube.conf
COPY config/php.ini /conf/
COPY config/config.inc.php /conf/
COPY login/mailu.php /var/www/webmail/plugins/mailu/
COPY config/config.inc.carddav.php /var/www/webmail/plugins/carddav/config.inc.php
# snappymail
ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.21.0/snappymail-2.21.0.tar.gz
RUN set -euxo pipefail \
; mkdir /var/www/snappymail \
; cd /var/www/snappymail \
; curl -sL ${SNAPPYMAIL_URL} | tar xz \
; chmod -R u+w,a+rX /var/www/snappymail \
; chown -R nginx:nginx /var/www/snappymail
# SnappyMail login
COPY snappymail/login/include.php /var/www/snappymail/
COPY snappymail/login/sso.php /var/www/snappymail/
# Parsed and moved at startup
COPY snappymail/defaults/application.ini /defaults/
COPY snappymail/defaults/default.json /defaults/
# common
COPY start.py /
COPY php.ini /defaults/
COPY php-webmail.conf /etc/php81/php-fpm.d/php-webmail.conf
COPY nginx-webmail.conf /conf/
EXPOSE 80/tcp
VOLUME /data

@ -2,7 +2,7 @@ server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/webmail;
root /var/www/{{ WEBMAIL }};
include /etc/nginx/mime.types;

@ -1,7 +1,7 @@
; Start a new pool named 'roundcube'.
; Start a new pool named 'php'.
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('roundcube' here)
[roundcube]
; pool name ('php' here)
[php]
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.

@ -2,7 +2,7 @@ expose_php=Off
date.timezone={{ TZ }}
upload_max_filesize = {{ MAX_FILESIZE }}M
post_max_size = {{ MAX_FILESIZE }}M
suhosin.session.encrypt=Off
session.auto_start=Off
mbstring.func_overload=Off
file_uploads=On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

@ -1,54 +0,0 @@
# syntax=docker/dockerfile-upstream:1.4.3
#snappymail image
FROM base
ARG VERSION
LABEL version=$VERSION
RUN set -euxo pipefail \
; apk add --no-cache \
nginx curl \
php81 php81-fpm php81-mbstring php81-zip php81-xml php81-simplexml \
php81-dom php81-curl php81-exif gd php81-gd php81-iconv php81-intl php81-openssl \
php81-pdo_sqlite php81-pdo php81-sodium libsodium php81-tidy php81-pecl-uuid \
; ln -s /usr/bin/php81 /usr/bin/php \
; rm /etc/nginx/http.d/default.conf \
; rm /etc/php81/php-fpm.d/www.conf \
; mkdir -p /run/nginx \
; mkdir -p /var/www/webmail \
; mkdir -p /config
# nginx / PHP config files
COPY config/nginx-snappymail.conf /config/
COPY config/php-snappymail.conf /etc/php81/php-fpm.d/snappymail.conf
# Parsed and moved at startup
COPY defaults/php.ini /defaults/
COPY defaults/application.ini /defaults/
COPY defaults/default.ini /defaults/
# Install Snappymail from source
ENV SNAPPYMAIL_URL https://github.com/the-djmaze/snappymail/releases/download/v2.19.4/snappymail-2.19.4.tar.gz
# Note. This is the last working snappymail version. 2.19.6 up to 2.20.6 do not work.
RUN set -euxo pipefail \
; cd /var/www/webmail \
; curl -sL ${SNAPPYMAIL_URL} | tar xz \
; chmod -R u+w,a+rX /var/www/webmail \
; chown -R nginx:nginx /var/www/webmail
# SnappyMail login
COPY login/include.php /var/www/webmail/
COPY login/sso.php /var/www/webmail/
COPY start.py /
COPY config.py /
EXPOSE 80/tcp
VOLUME ["/data"]
CMD /start.py
HEALTHCHECK CMD curl -f -L http://localhost/ping || exit 1
RUN echo $VERSION >> /version

@ -1,16 +0,0 @@
#!/usr/bin/env python3
import os
import logging as log
import sys
from socrate import system, conf
args = os.environ.copy()
log.basicConfig(stream=sys.stderr, level=args.get("LOG_LEVEL", "WARNING"))
# Build final configuration paths
conf.jinja("/config/nginx-snappymail.conf", args, "/etc/nginx/http.d/snappymail.conf")
if os.path.exists("/var/run/nginx.pid"):
os.system("nginx -s reload")

@ -1,118 +0,0 @@
; Start a new pool named 'snappymail'.
; the variable $pool can be used in any directive and will be replaced by the
; pool name ('snappymail' here)
[snappymail]
; Redirect worker stdout and stderr into main error log. If not set, stdout and
; stderr will be redirected to /dev/null according to FastCGI specs.
; Default value: no.
catch_workers_output = 1
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = nginx
group = nginx
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on
; a specific port;
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses
; (IPv6 and IPv4-mapped) on a specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /var/run/php8-fpm.sock
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0660
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
; Choose how the process manager will control the number of child processes.
; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; dynamic - the number of child processes are set dynamically based on the
; following directives. With this process management, there will be
; always at least 1 children.
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; pm.start_servers - the number of children created on startup.
; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used:
; pm.max_children - the maximum number of children that
; can be alive at the same time.
; pm.process_idle_timeout - The number of seconds after which
; an idle process will be killed.
; Note: This value is mandatory.
pm = ondemand
; The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
; This value sets the limit on the number of simultaneous requests that will be
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
; CGI. The below defaults are based on a server without much resources. Don't
; forget to tweak pm.* to fit your needs.
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
; Note: This value is mandatory.
pm.max_children = 5
; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
; pm.start_servers = 2
; The desired minimum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; pm.min_spare_servers = 1
; The desired maximum number of idle server processes.
; Note: Used only when pm is set to 'dynamic'
; Note: Mandatory when pm is set to 'dynamic'
; pm.max_spare_servers = 3
; This sets the maximum time in seconds a script is allowed to run before it is
; terminated by the parser. This helps prevent poorly written scripts from tying up
; the server. The default setting is 30s.
; Note: Used only when pm is set to 'ondemand'
pm.process_idle_timeout = 10s
; The number of requests each child process should execute before respawning.
; This can be useful to work around memory leaks in 3rd party libraries. For endless
; request processing specify '0'.
; Equivalent to PHP_FCGI_MAX_REQUESTS. Default value: 0.
; Noted: Used only when pm is set to 'ondemand'
pm.max_requests = 200
; The ping URI to call the monitoring page of FPM. If this value is not set, no
; URI will be recognized as a ping page. This could be used to test from outside
; that FPM is alive and responding, or to
; - create a graph of FPM availability (rrd or such);
; - remove a server from a group if it is not responding (load balancing);
; - trigger alerts for the operating team (24/7).
; Note: The value must start with a leading slash (/). The value can be
; anything, but it may not be a good idea to use the .php extension or it
; may conflict with a real PHP file.
; Default Value: not set
ping.path = /ping
; This directive may be used to customize the response of a ping request. The
; response is formatted as text/plain with a 200 response code.
; Default Value: pong
;ping.response = pong

@ -1,15 +0,0 @@
imap_host = "{{ FRONT_ADDRESS }}"
imap_port = 10143
imap_secure = "None"
imap_short_login = Off
sieve_use = On
sieve_allow_raw = Off
sieve_host = "{{ IMAP_ADDRESS }}"
sieve_port = 4190
sieve_secure = "None"
smtp_host = "{{ FRONT_ADDRESS }}"
smtp_port = 10025
smtp_secure = "None"
smtp_short_login = Off
smtp_auth = On
smtp_php_mail = Off

@ -0,0 +1,50 @@
{
"name": "*",
"IMAP": {
"host": "{{ FRONT_ADDRESS }}",
"port": 10143,
"secure": 0,
"shortLogin": false,
"ssl": {
"verify_peer": false,
"verify_peer_name": false,
"allow_self_signed": false,
"SNI_enabled": true,
"disable_compression": true,
"security_level": 1
}
},
"SMTP": {
"host": "{{ FRONT_ADDRESS }}",
"port": 10025,
"secure": 0,
"shortLogin": false,
"ssl": {
"verify_peer": false,
"verify_peer_name": false,
"allow_self_signed": false,
"SNI_enabled": true,
"disable_compression": true,
"security_level": 1
},
"useAuth": true,
"setSender": false,
"usePhpMail": false
},
"Sieve": {
"host": "{{ IMAP_ADDRESS }}",
"port": 4190,
"secure": 0,
"shortLogin": false,
"ssl": {
"verify_peer": false,
"verify_peer_name": false,
"allow_self_signed": false,
"SNI_enabled": true,
"disable_compression": true,
"security_level": 1
},
"enabled": true
},
"whiteList": ""
}

@ -1,5 +0,0 @@
expose_php=Off
date.timezone={{ TZ }}
upload_max_filesize = {{ MAX_FILESIZE }}M
post_max_size = {{ MAX_FILESIZE }}M

@ -1,34 +0,0 @@
#!/usr/bin/env python3
import os
import shutil
import logging as log
import sys
import subprocess
from socrate import system, conf
log.basicConfig(stream=sys.stderr, level=os.environ.get("LOG_LEVEL", "WARNING"))
# Actual startup script
os.environ["FRONT_ADDRESS"] = system.resolve_address(os.environ.get("HOST_FRONT", "front"))
os.environ["IMAP_ADDRESS"] = system.resolve_address(os.environ.get("HOST_IMAP", "imap"))
os.environ["MAX_FILESIZE"] = str(int(int(os.environ.get("MESSAGE_SIZE_LIMIT"))*0.66/1048576))
base = "/data/_data_/_default_/"
shutil.rmtree(base + "domains/", ignore_errors=True)
os.makedirs(base + "domains", exist_ok=True)
os.makedirs(base + "configs", exist_ok=True)
conf.jinja("/defaults/default.ini", os.environ, "/data/_data_/_default_/domains/default.ini")
conf.jinja("/defaults/application.ini", os.environ, "/data/_data_/_default_/configs/application.ini")
conf.jinja("/defaults/php.ini", os.environ, "/etc/php81/php.ini")
# Start the fastcgi process manager now that config files have been adjusted
os.system("php-fpm81")
os.system("chown -R nginx:nginx /data")
os.system("chmod -R a+rX /var/www/webmail/")
subprocess.call(["/config.py"])
os.execv("/usr/sbin/nginx", ["nginx", "-g", "daemon off;"])

@ -4,9 +4,10 @@ import os
import logging
import sys
import subprocess
import shutil
import hmac
from socrate import conf
from socrate import conf, system
env = os.environ
@ -17,6 +18,8 @@ context = {}
context.update(env)
context["MAX_FILESIZE"] = str(int(int(env.get("MESSAGE_SIZE_LIMIT", "50000000")) * 0.66 / 1048576))
context["FRONT_ADDRESS"] = system.resolve_address(os.environ.get("HOST_FRONT", "front"))
context["IMAP_ADDRESS"] = system.resolve_address(os.environ.get("HOST_IMAP", "imap"))
db_flavor = env.get("ROUNDCUBE_DB_FLAVOR", "sqlite")
if db_flavor == "sqlite":
@ -52,7 +55,7 @@ context['SECRET_KEY'] = hmac.new(bytearray(secret_key, 'utf-8'), bytearray('ROUN
# roundcube plugins
# (using "dict" because it is ordered and "set" is not)
plugins = dict((p, None) for p in env.get("ROUNDCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/webmail/plugins", p)))
plugins = dict((p, None) for p in env.get("ROUNDCUBE_PLUGINS", "").replace(" ", "").split(",") if p and os.path.isdir(os.path.join("/var/www/roundcube/plugins", p)))
if plugins:
plugins["mailu"] = None
else:
@ -67,15 +70,14 @@ context["INCLUDES"] = sorted(inc for inc in os.listdir("/overrides") if inc.ends
context["SESSION_TIMEOUT_MINUTES"] = max(int(env.get("SESSION_TIMEOUT", "3600")) // 60, 1)
# create config files
conf.jinja("/conf/php.ini", context, "/etc/php81/php.ini")
conf.jinja("/conf/config.inc.php", context, "/var/www/webmail/config/config.inc.php")
conf.jinja("/conf/config.inc.php", context, "/var/www/roundcube/config/config.inc.php")
# create dirs
os.system("mkdir -p /data/gpg")
print("Initializing database")
try:
result = subprocess.check_output(["/var/www/webmail/bin/initdb.sh", "--dir", "/var/www/webmail/SQL"],
result = subprocess.check_output(["/var/www/roundcube/bin/initdb.sh", "--dir", "/var/www/roundcube/SQL"],
stderr=subprocess.STDOUT)
print(result.decode())
except subprocess.CalledProcessError as exc:
@ -88,22 +90,31 @@ except subprocess.CalledProcessError as exc:
print("Upgrading database")
try:
subprocess.check_call(["/var/www/webmail/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
subprocess.check_call(["/var/www/roundcube/bin/update.sh", "--version=?", "-y"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
exit(4)
else:
print("Cleaning database")
try:
subprocess.check_call(["/var/www/webmail/bin/cleandb.sh"], stderr=subprocess.STDOUT)
subprocess.check_call(["/var/www/roundcube/bin/cleandb.sh"], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as exc:
exit(5)
base = "/data/_data_/_default_/"
shutil.rmtree(base + "domains/", ignore_errors=True)
os.makedirs(base + "domains", exist_ok=True)
os.makedirs(base + "configs", exist_ok=True)
conf.jinja("/defaults/default.json", context, "/data/_data_/_default_/domains/default.json")
conf.jinja("/defaults/application.ini", context, "/data/_data_/_default_/configs/application.ini")
conf.jinja("/defaults/php.ini", context, "/etc/php81/php.ini")
# setup permissions
os.system("chown -R nginx:nginx /data")
os.system("chmod -R a+rX /var/www/webmail/")
os.system("chown -R nginx:nginx /data /var/www")
os.system("chmod -R a+rX /var/www/")
# Configure nginx
conf.jinja("/conf/nginx-roundcube.conf", context, "/etc/nginx/http.d/roundcube.conf")
conf.jinja("/conf/nginx-webmail.conf", context, "/etc/nginx/http.d/webmail.conf")
if os.path.exists("/var/run/nginx.pid"):
os.system("nginx -s reload")
Loading…
Cancel
Save