.tld`` will likely result in a 404 error).
diff --git a/docs/kubernetes/stable/kubernetes-mailu.yaml b/docs/kubernetes/stable/kubernetes-mailu.yaml
deleted file mode 100644
index a7bafccd..00000000
--- a/docs/kubernetes/stable/kubernetes-mailu.yaml
+++ /dev/null
@@ -1,419 +0,0 @@
----
-apiVersion: extensions/v1beta1
-kind: Ingress
-metadata:
- name: mailu-admin-ing
- labels:
- app: mailu
- role: mail
- tier: backend
-spec:
- tls:
- - hosts:
- - "mail.example.com"
- secretName: letsencrypt-certs-all # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt
- rules:
- - host: "mail.example.com"
- http:
- paths:
- - path: "/admin"
- backend:
- serviceName: mailu-admin
- servicePort: 80
-
----
-apiVersion: extensions/v1beta1
-kind: Deployment
-metadata:
- name: mailu-redis
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-redis
- role: mail
- tier: backend
- spec:
- containers:
- - name: redis
- image: redis:4.0-alpine
- imagePullPolicy: Always
- volumeMounts:
- - mountPath: /data
- name: redisdata
- ports:
- - containerPort: 6379
- name: redis
- protocol: TCP
- volumes:
- - name: redisdata
- hostPath:
- path: /var/data/mailu/redisdata
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: redis
- labels:
- app: mailu-redis
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu
- role: mail
- tier: backend
- ports:
- - name: redis
- port: 6379
- protocol: TCP
-
----
-
-apiVersion: extensions/v1beta1
-kind: Deployment
-metadata:
- name: mailu-imap
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-imap
- role: mail
- tier: backend
- spec:
- containers:
- - name: imap
- image: mailu/dovecot:stable
- imagePullPolicy: Always
- env:
- - name : DOMAIN
- value : example.com
- - name : HOSTNAME
- value : mail.example.com
- - name : POSTMASTER
- value : admin
- volumeMounts:
- - mountPath: /data
- name: maildata
- - mountPath: /mail
- name: mailstate
- - mountPath: /overrides
- name: overrides
- - mountPath: /certs
- name: certs
- readOnly: true
- ports:
- - containerPort: 2102
- - containerPort: 2525
- - containerPort: 143
- - containerPort: 993
- - containerPort: 4190
- volumes:
- - name: maildata
- hostPath:
- path: /var/data/mailu/maildata
- - name: mailstate
- hostPath:
- path: /var/data/mailu/mailstate
- - name: overrides
- hostPath:
- path: /var/data/mailu/overrides
- - name: certs
- secret:
- items:
- - key: tls.crt
- path: cert.pem
- - key: tls.key
- path: key.pem
- secretName: letsencrypt-certs-all
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: imap
- labels:
- app: mailu
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-imap
- role: mail
- tier: backend
- ports:
- ports:
- - name: imap-auth
- port: 2102
- protocol: TCP
- - name: imap-transport
- port: 2525
- protocol: TCP
- - name: imap-default
- port: 143
- protocol: TCP
- - name: imap-ssl
- port: 993
- protocol: TCP
- - name: sieve
- port: 4190
- protocol: TCP
-
----
-
-apiVersion: extensions/v1beta1
-kind: Deployment
-metadata:
- name: mailu-smtp
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-smtp
- role: mail
- tier: backend
- spec:
- containers:
- - name: smtp
- image: mailu/postfix:stable
- imagePullPolicy: Always
- env:
- - name : DOMAIN
- value : example.com
- - name : HOSTNAME
- value : mail.example.com
- - name : MESSAGE_SIZE_LIMIT
- value : "50000000"
- - name : RELAYHOST
- value : ""
- volumeMounts:
- - mountPath: /data
- name: maildata
- - mountPath: /overrides
- name: overrides
- - mountPath: /certs
- name: certs
- readOnly: true
- ports:
- - name: smtp
- containerPort: 25
- protocol: TCP
- - name: smtp-ssl
- containerPort: 465
- protocol: TCP
- - name: smtp-starttls
- containerPort: 587
- protocol: TCP
- volumes:
- - name: maildata
- hostPath:
- path: /var/data/mailu/maildata
- - name: overrides
- hostPath:
- path: /var/data/mailu/overrides
- - name: certs
- secret:
- items:
- - key: tls.crt
- path: cert.pem
- - key: tls.key
- path: key.pem
- secretName: letsencrypt-certs-all
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: smtp
- labels:
- app: mailu
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-smtp
- role: mail
- tier: backend
- ports:
- - name: smtp
- port: 25
- protocol: TCP
- - name: smtp-ssl
- port: 465
- protocol: TCP
- - name: smtp-starttls
- port: 587
- protocol: TCP
-
----
-
-apiVersion: extensions/v1beta1
-kind: Deployment
-metadata:
- name: mailu-security
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-security
- role: mail
- tier: backend
- spec:
- containers:
- - name: antispam
- image: mailu/rspamd:stable
- imagePullPolicy: Always
- ports:
- - name: antispam
- containerPort: 11333
- protocol: TCP
- volumeMounts:
- - name: filter
- mountPath: /var/lib/rspamd
- - name: antivirus
- image: mailu/clamav:stable
- imagePullPolicy: Always
- ports:
- - name: antivirus
- containerPort: 3310
- protocol: TCP
- volumeMounts:
- - name: filter
- mountPath: /data
- volumes:
- - name: filter
- hostPath:
- path: /var/data/mailu/filter
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: antispam
- labels:
- app: mailu-antispam
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-security
- role: mail
- tier: backend
- ports:
- - name: antispam
- port: 11333
- protocol: TCP
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: antivirus
- labels:
- app: mailu-antivirus
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-security
- role: mail
- tier: backend
- ports:
- - name: antivirus
- port: 3310
- protocol: TCP
-
----
-
-apiVersion: extensions/v1beta1
-kind: Deployment
-metadata:
- name: mailu-admin
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- app: mailu-admin
- role: mail
- tier: backend
- spec:
- containers:
- - name: admin
- image: mailu/admin:stable
- imagePullPolicy: Always
- env:
- - name : DOMAIN
- value : example.com
- - name : HOSTNAME
- value : mail.example.com
- - name : POSTMASTER
- value : core
- - name : SECRET_KEY
- value : pleasereplacethiswithabetterkey
- - name : DEBUG
- value : "True"
- volumeMounts:
- - name: maildata
- mountPath: /data
- - name: dkim
- mountPath: /dkim
- - name: certs
- mountPath: /certs
- readOnly: true
- # - name: docker
- # mountPath: /var/run/docker.sock
- # readOnly: true
- ports:
- - name: http
- containerPort: 80
- protocol: TCP
- volumes:
- - name: maildata
- hostPath:
- path: /var/data/mailu/maildata
- - name: dkim
- hostPath:
- path: /var/data/mailu/dkim
- - name: certs
- secret:
- items:
- - key: tls.crt
- path: cert.pem
- - key: tls.key
- path: key.pem
- secretName: letsencrypt-certs-all
- # - name: docker
- # hostPath:
- # path: /var/run/docker.sock
-
----
-
-apiVersion: v1
-kind: Service
-metadata:
- name: mailu-admin
- labels:
- app: mailu-admin
- role: mail
- tier: backend
-spec:
- selector:
- app: mailu-admin
- role: mail
- tier: backend
- ports:
- - name: http
- port: 80
- protocol: TCP
diff --git a/docs/kubernetes/stable/kubernetes-nginx-ingress-controller.yaml b/docs/kubernetes/stable/kubernetes-nginx-ingress-controller.yaml
deleted file mode 100644
index 5ea9790a..00000000
--- a/docs/kubernetes/stable/kubernetes-nginx-ingress-controller.yaml
+++ /dev/null
@@ -1,84 +0,0 @@
----
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: nginx-configuration
- namespace: ingress-nginx
- labels:
- app: ingress-nginx
-
----
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: udp-services
- namespace: ingress-nginx
-
----
-kind: ConfigMap
-apiVersion: v1
-metadata:
- name: tcp-services
- namespace: ingress-nginx
-data:
- 25: "mailu/smtp:25"
- 465: "mailu/smtp:465"
- 587: "mailu/smtp:587"
- 143: "mailu/imap:143"
- 993: "mailu/imap:993"
-
----
-apiVersion: extensions/v1beta1
-kind: Deployment
-metadata:
- name: nginx-ingress-controller
- namespace: kube-system
- labels:
- k8s-app: nginx-ingress-controller
-spec:
- replicas: 1
- template:
- metadata:
- labels:
- k8s-app: nginx-ingress-controller
- annotations:
- prometheus.io/port: '10254'
- prometheus.io/scrape: 'true'
- spec:
- # hostNetwork makes it possible to use ipv6 and to preserve the source IP correctly regardless of docker configuration
- # however, it is not a hard dependency of the nginx-ingress-controller itself and it may cause issues if port 10254 already is taken on the host
- # that said, since hostPort is broken on CNI (https://github.com/kubernetes/kubernetes/issues/31307) we have to use hostNetwork where CNI is used
- # like with kubeadm
- # hostNetwork: true
- terminationGracePeriodSeconds: 60
- containers:
- - image: gcr.io/google_containers/nginx-ingress-controller:0.11.0
- name: nginx-ingress-controller
- args:
- - /nginx-ingress-controller
- - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
- - --configmap=$(POD_NAMESPACE)/nginx-configuration
- - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- - --annotations-prefix=nginx.ingress.kubernetes.io
- readinessProbe:
- httpGet:
- path: /healthz
- port: 10254
- scheme: HTTP
- livenessProbe:
- httpGet:
- path: /healthz
- port: 10254
- scheme: HTTP
- initialDelaySeconds: 10
- timeoutSeconds: 1
- env:
- - name: POD_NAME
- valueFrom:
- fieldRef:
- fieldPath: metadata.name
- - name: POD_NAMESPACE
- valueFrom:
- fieldRef:
- fieldPath: metadata.namespace
diff --git a/optional/clamav/Dockerfile b/optional/clamav/Dockerfile
index a27c0eb2..3a9bf4aa 100644
--- a/optional/clamav/Dockerfile
+++ b/optional/clamav/Dockerfile
@@ -4,8 +4,11 @@ RUN apk add --no-cache clamav rsyslog wget clamav-libunrar
COPY conf /etc/clamav
COPY start.sh /start.sh
+COPY health.sh /health.sh
EXPOSE 3310/tcp
VOLUME ["/data"]
CMD ["/start.sh"]
+
+HEALTHCHECK CMD /health.sh
diff --git a/optional/clamav/health.sh b/optional/clamav/health.sh
new file mode 100755
index 00000000..c4c55044
--- /dev/null
+++ b/optional/clamav/health.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [ "$(echo PING | nc localhost 3310)" = "PONG" ]; then
+ echo "ping successful"
+else
+ echo "ping failed"
+ exit 1
+fi
diff --git a/optional/radicale/Dockerfile b/optional/radicale/Dockerfile
index b82a0804..4616d53d 100644
--- a/optional/radicale/Dockerfile
+++ b/optional/radicale/Dockerfile
@@ -1,7 +1,7 @@
FROM alpine:edge
RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \
- && apk add --no-cache radicale@testing py-dulwich@testing
+ && apk add --no-cache radicale@testing py-dulwich@testing curl
COPY radicale.conf /radicale.conf
@@ -9,3 +9,5 @@ EXPOSE 5232/tcp
VOLUME ["/data"]
CMD radicale -f -S -C /radicale.conf
+
+HEALTHCHECK CMD curl -f -L http://localhost:5232/ || exit 1
diff --git a/services/rspamd/Dockerfile b/services/rspamd/Dockerfile
index 24da3c9f..76731c9a 100644
--- a/services/rspamd/Dockerfile
+++ b/services/rspamd/Dockerfile
@@ -1,6 +1,6 @@
FROM alpine:3.8
-RUN apk add --no-cache python py-jinja2 rspamd rspamd-controller rspamd-proxy rspamd-fuzzy ca-certificates py-pip \
+RUN apk add --no-cache python py-jinja2 rspamd rspamd-controller rspamd-proxy rspamd-fuzzy ca-certificates py-pip curl\
&& pip install --upgrade pip \
&& pip install tenacity
@@ -14,3 +14,5 @@ EXPOSE 11332/tcp 11334/tcp 11335/tcp
VOLUME ["/var/lib/rspamd"]
CMD /start.py
+
+HEALTHCHECK --start-period=350s CMD curl -f -L http://localhost:11334/ || exit 1
diff --git a/setup/Dockerfile b/setup/Dockerfile
index 1fc808f1..83711af5 100644
--- a/setup/Dockerfile
+++ b/setup/Dockerfile
@@ -4,15 +4,19 @@ RUN mkdir -p /app
WORKDIR /app
COPY requirements.txt requirements.txt
-RUN apk add --no-cache git \
+RUN apk add --no-cache git curl \
&& pip install -r requirements.txt
COPY server.py ./server.py
COPY setup.py ./setup.py
COPY main.py ./main.py
+COPY flavors /data/master/flavors
+COPY templates /data/master/templates
-RUN python setup.py https://github.com/mailu/mailu /data
+#RUN python setup.py https://github.com/mailu/mailu /data
EXPOSE 80/tcp
CMD gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload main:app
+
+HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1
diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml
index 9288bb7e..e91332e1 100644
--- a/setup/docker-compose.yml
+++ b/setup/docker-compose.yml
@@ -9,5 +9,6 @@ services:
setup:
image: mailu/setup
ports:
- - "80:80"
+ - "8000:80"
+ build: .
diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml
index fcf0c092..b01bb8fd 100644
--- a/setup/flavors/compose/docker-compose.yml
+++ b/setup/flavors/compose/docker-compose.yml
@@ -1,124 +1,106 @@
{% set env='mailu.env' %}
# This file is auto-generated by the Mailu configuration wizard.
# Please read the documentation before attempting any change.
+# Generated for {{ flavor }} flavor
-version: '2'
+version: '3.6'
services:
# External dependencies
redis:
image: redis:alpine
- restart: always
volumes:
- - "$ROOT/redis:/data"
+ - "{{ root }}/redis:/data"
# Core services
front:
image: mailu/nginx:{{ version }}
- restart: always
env_file: {{ env }}
- env:
- - TLS_FLAVOR={{ tls_flavor or 'letsencrypt' }}
- - ADMIN={{ expose_admin or 'no' }}
ports:
{% for port in (80, 443, 25, 465, 587, 110, 995, 143, 993) %}
{% if bind4 %}
- - "$PUBLIC_IPV4:{{ port }}:{{ port }}"
+ - "{{ bind4 }}:{{ port }}:{{ port }}"
{% endif %}
{% if bind6 %}
- - "$PUBLIC_IPV6:{{ port }}:{{ port }}"
+ - "{{ bind6 }}:{{ port }}:{{ port }}"
{% endif %}
{% endfor %}
- {% if flavor in ('cert', 'mail') %}
volumes:
- - "$ROOT/certs:/certs"
- {% endif %}
+ - "{{ root }}/certs:/certs"
admin:
image: mailu/admin:{{ version }}
- restart: always
env_file: {{ env }}
- {% if not expose_admin %}
+ {% if not admin_enabled %}
ports:
- 127.0.0.1:8080:80
{% endif %}
volumes:
- - "$ROOT/data:/data"
- - "$ROOT/dkim:/dkim"
+ - "{{ root }}/data:/data"
+ - "{{ root }}/dkim:/dkim"
depends_on:
- redis
imap:
image: mailu/dovecot:{{ version }}
- restart: always
env_file: {{ env }}
volumes:
- - "$ROOT/data:/data"
- - "$ROOT/mail:/mail"
- - "$ROOT/overrides:/overrides"
+ - "{{ root }}/mail:/mail"
+ - "{{ root }}/overrides:/overrides"
depends_on:
- front
smtp:
image: mailu/postfix:{{ version }}
- restart: always
env_file: {{ env }}
volumes:
- - "$ROOT/data:/data"
- - "$ROOT/overrides:/overrides"
+ - "{{ root }}/overrides:/overrides"
depends_on:
- front
# Optional services
- {% if enable_antispam %}
+ {% if antispam_enabled %}
antispam:
image: mailu/rspamd:{{ version }}
- restart: always
env_file: {{ env }}
volumes:
- - "$ROOT/filter:/var/lib/rspamd"
- - "$ROOT/dkim:/dkim"
- - "$ROOT/overrides/rspamd:/etc/rspamd/override.d"
+ - "{{ root }}/filter:/var/lib/rspamd"
+ - "{{ root }}/dkim:/dkim"
+ - "{{ root }}/overrides/rspamd:/etc/rspamd/override.d"
depends_on:
- front
{% endif %}
- {% if enable_antivirus %}
+ {% if antivirus_enabled %}
antivirus:
image: mailu/clamav:{{ version }}
- restart: always
env_file: {{ env }}
volumes:
- - "$ROOT/filter:/data"
+ - "{{ root }}/filter:/data"
{% endif %}
- {% if enable_webdav %}
+ {% if webdav_enabled %}
webdav:
- image: mailu/radivale:{{ version }}
- restart: always
+ image: mailu/radicale:{{ version }}
env_file: {{ env }}
volumes:
- - "$ROOT/dav:/data"
+ - "{{ root }}/dav:/data"
{% endif %}
- {% if enable_fetchmail %}
+ {% if fetchmail_enabled %}
fetchmail:
image: mailu/fetchmail:{{ version }}
- restart: always
env_file: {{ env }}
- volumes:
- - "$ROOT/data:/data"
{% endif %}
# Webmail
- {% if enable_webmail %}
+ {% if webmail_type != 'none' %}
webmail:
- image: mailu/{{ webmail }}:{{ version }}
- restart: always
+ image: mailu/{{ webmail_type }}:{{ version }}
env_file: {{ env }}
volumes:
- - "$ROOT/webmail:/data"
+ - "{{ root }}/webmail:/data"
depends_on:
- imap
{% endif %}
diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env
index 24d7b247..9fc1197d 100644
--- a/setup/flavors/compose/mailu.env
+++ b/setup/flavors/compose/mailu.env
@@ -1,5 +1,7 @@
# Mailu main configuration file
#
+# Generated for {{ flavor }} flavor
+#
# This file is autogenerated by the configuration management wizard.
# For a detailed list of configuration variables, see the documentation at
# https://mailu.io
@@ -9,60 +11,118 @@
###################################
# Set this to the path where Mailu data and configuration is stored
-ROOT=/mailu
+# This variable is now set directly in `docker-compose.yml by the setup utility
+# ROOT={{ root }}
+
+# Mailu version to run (1.0, 1.1, etc. or master)
+#VERSION={{ version }}
# Set to a randomly generated 16 bytes string
SECRET_KEY={{ secret(16) }}
# Address where listening ports should bind
-{% if bind4 %}PUBLIC_IPV4={{ bind4 }}{% endif %}
-{% if bind6 %}PUBLIC_IPV6={{ bind6 }}{% endif %}
+# This variables are now set directly in `docker-compose.yml by the setup utility
+# PUBLIC_IPV4= {{ bind4 }} (default: 127.0.0.1)
+# PUBLIC_IPV6= {{ bind6 }} (default: ::1)
-# Mail address of the postmaster
-POSTMASTER={{ postmaster }}
+# Main mail domain
+DOMAIN={{ domain }}
# Hostnames for this server, separated with comas
HOSTNAMES={{ hostnames }}
+# Postmaster local part (will append the main mail domain)
+POSTMASTER={{ postmaster }}
+
+# Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt)
+TLS_FLAVOR={{ tls_flavor }}
+
# Authentication rate limit (per source IP address)
-AUTH_RATELIMIT={{ auth_ratelimit }}
+{% if auth_ratelimit_pm > '0' and auth_ratelimit_ph > '0' %}
+AUTH_RATELIMIT={{ auth_ratelimit_pm }}/minute;{{ auth_ratelimit_ph }}/hour
+{% endif %}
# Opt-out of statistics, replace with "True" to opt out
-DISABLE_STATISTICS={{ disable_statistics }}
+DISABLE_STATISTICS={{ disable_statistics or 'False' }}
###################################
-# Server behavior
+# Optional features
+###################################
+
+# Expose the admin interface (value: true, false)
+ADMIN={{ admin_enabled or 'false' }}
+
+# Choose which webmail to run if any (values: roundcube, rainloop, none)
+WEBMAIL={{ webmail_type }}
+
+# Dav server implementation (value: radicale, none)
+WEBDAV={{ webdav_enabled or 'none' }}
+
+# Antivirus solution (value: clamav, none)
+#ANTIVIRUS={{ antivirus_enabled or 'none' }}
+
+#Antispam solution
+ANTISPAM={{ antispam_enabled or 'none'}}
+
+###################################
+# Mail settings
###################################
# Message size limit in bytes
# Default: accept messages up to 50MB
-MESSAGE_SIZE_LIMIT={{ message_size_limit }}
+MESSAGE_SIZE_LIMIT={{ message_size_limit or '50000000' }}
# Networks granted relay permissions, make sure that you include your Docker
# internal network (default to 172.17.0.0/16)
-RELAYNETS={{ relaynets }}
+RELAYNETS={{ relaynets or '172.17.0.0/16' }}
# Will relay all outgoing mails if configured
RELAYHOST={{ relayhost }}
# Fetchmail delay
-FETCHMAIL_DELAY={{ fetchmail_delay }}
+FETCHMAIL_DELAY={{ fetchmail_delay or '600' }}
# Recipient delimiter, character used to delimiter localpart from custom address part
-RECIPIENT_DELIMITER={{ recipient_delimiter }}
+RECIPIENT_DELIMITER={{ recipient_delimiter or '+' }}
-{% if dmarc_rua or dmarc_ruf %}
# DMARC rua and ruf email
-{% if dmarc_rua %}DMARC_RUA={{ dmarc_rua }}{% endif %}
-{% if dmarc_ruf %}DMARC_RUF={{ dmarc_ruf }}{% endif %}
-{% endif %}
+DMARC_RUA={{ dmarc_rua or 'admin' }}
+DMARC_RUF={{ dmarc_ruf or 'admin' }}
{% if welcome_enabled %}
# Welcome email, enable and set a topic and body if you wish to send welcome
# emails to all users.
-WELCOME={{ welcome_enable }}
-WELCOME_SUBJECT={{ welcome_subject }}
-WELCOME_BODY={{ welcome_body }}
+WELCOME={{ welcome_enable or 'false' }}
+WELCOME_SUBJECT={{ welcome_subject or 'Welcome to your new email account' }}
+WELCOME_BODY={{ welcome_body or 'Welcome to your new email account, if you can read this, then it is configured properly!' }}
+{% endif %}
+
+# Maildir Compression
+# choose compression-method, default: none (value: bz2, gz)
+COMPRESSION={{ compression }}
+# change compression-level, default: 6 (value: 1-9)
+COMPRESSION_LEVEL={{ compression_level }}
+
+###################################
+# Web settings
+###################################
+
+# Path to the admin interface if enabled
+WEB_ADMIN={{ admin_path }}
+
+# Path to the webmail if enabled
+WEB_WEBMAIL={{ webmail_path }}
+
+# Website name
+SITENAME={{ site_name }}
+
+# Linked Website URL
+WEBSITE={{ website }}
+
+{% if recaptcha_public_key and recaptcha_private_key %}
+# Registration reCaptcha settings (warning, this has some privacy impact)
+# RECAPTCHA_PUBLIC_KEY={{ recaptcha_public_key }}
+# RECAPTCHA_PRIVATE_KEY={{ recaptcha_private_key }}
{% endif %}
{% if domain_registration %}
@@ -70,39 +130,28 @@ WELCOME_BODY={{ welcome_body }}
DOMAIN_REGISTRATION=true
{% endif %}
-###################################
-# Web settings
-###################################
-
-# Path to the admin interface if enabled
-WEB_ADMIN=/admin
-
-# Path to the webmail if enabled
-WEB_WEBMAIL=/webmail
-
-# Website name
-SITENAME=Mailu
-
-# Linked Website URL
-WEBSITE=https://mailu.io
-
-{% if recaptcha_public_key and recaptcha_private_key %}
-# Registration reCaptcha settings (warning, this has some privacy impact)
-# RECAPTCHA_PUBLIC_KEY={{ recaptcha_public_key }}
-# RECAPTCHA_PRIVATE_KEY={{ recaptcha_private_key }}
-{% endif %}
-
###################################
# Advanced settings
###################################
-{% if password_scheme %}
-# Specific password storage scheme
-PASSWORD_SCHEME={{ password_scheme }}
-{% endif %}
+# Log driver for front service. Possible values:
+# json-file (default)
+# journald (On systemd platforms, useful for Fail2Ban integration)
+# syslog (Non systemd platforms, Fail2Ban integration. Disables `docker-compose log` for front!)
+LOG_DRIVER={{ log_driver or 'json-file' }}
+
+# Docker-compose project name, this will prepended to containers names.
+COMPOSE_PROJECT_NAME={{ compose_project_name or 'mailu' }}
+
+# Default password scheme used for newly created accounts and changed passwords
+# (value: BLF-CRYPT, SHA512-CRYPT, SHA256-CRYPT, MD5-CRYPT, CRYPT)
+PASSWORD_SCHEME={{ password_scheme or 'BLF-CRYPT' }}
# Header to take the real ip from
REAL_IP_HEADER={{ real_ip_header }}
# IPs for nginx set_real_ip_from (CIDR list separated by commas)
REAL_IP_FROM={{ real_ip_from }}
+
+# choose wether mailu bounces (no) or rejects (yes) mail when recipient is unknown (value: yes, no)
+REJECT_UNLISTED_RECIPIENT={{ reject_unlisted_recipient }}
diff --git a/setup/flavors/compose/setup.html b/setup/flavors/compose/setup.html
index e4506e6d..0379ba82 100644
--- a/setup/flavors/compose/setup.html
+++ b/setup/flavors/compose/setup.html
@@ -4,15 +4,15 @@
Docker Compose expects a project file, named docker-compose.yml
in a project directory. First create your project directory.
-mkdir /mailu
+mkdir {{ root }}
Then download the project file. A side configuration file makes it easier
to read and check the configuration variables generated by the wizard.
-cd /mailu
-wget {{ url_for('.file', uid=uid, filepath='docker-compose.yml', _external=True) }}
-wget {{ url_for('.file', uid=uid, filepath='mailu.env', _external=True) }}
+cd {{ root }}
+curl {{ url_for('.file', uid=uid, filepath='docker-compose.yml', _external=True) }} > docker-compose.yml
+curl {{ url_for('.file', uid=uid, filepath='mailu.env', _external=True) }} > mailu.env
{% endcall %}
@@ -30,7 +30,22 @@ files before going any further.
To start your compose project, simply run the Docker Compose up
command.
-cd /mailu
+cd {{ root }}
docker-compose up -d
+
+Before you can use Mailu, you must create the primary administrator user account. This should be {{ postmaster }}@{{ domain }}. Use the following command, changing PASSWORD to your liking:
+
+docker-compose exec admin python manage.py admin {{ postmaster }} {{ domain }} PASSWORD
+
+
+Login to the admin interface to change the password for a safe one, at
+{% if admin_enabled %}
+one of the hostnames
+{{ hostnames.split(',')[0] }}{{ admin_path }} .
+{% else %}
+http://127.0.0.1:8080 (only directly from the host running docker).
+{% endif %}
+And choose the "Update password" option in the left menu.
+
{% endcall %}
diff --git a/setup/flavors/stack/docker-compose.yml b/setup/flavors/stack/docker-compose.yml
new file mode 100644
index 00000000..f27b661f
--- /dev/null
+++ b/setup/flavors/stack/docker-compose.yml
@@ -0,0 +1,128 @@
+{% set env='mailu.env' %}
+# This file is auto-generated by the Mailu configuration wizard.
+# Please read the documentation before attempting any change.
+# Generated for {{ flavor }} flavor
+
+version: '3.6'
+
+services:
+
+# External dependencies
+ redis:
+ image: redis:alpine
+ restart: always
+ volumes:
+ - "{{ root }}/redis:/data"
+
+# Core services
+ front:
+ image: mailu/nginx:{{ version }}
+ env_file: {{ env }}
+ ports:
+ {% for port in (80, 443, 25, 465, 587, 110, 995, 143, 993) %}
+ - target: {{ port }}
+ published: {{ port }}
+ mode: overlay
+ {% endfor %}
+ volumes:
+ - "{{ root }}/certs:/certs"
+ deploy:
+ replicas: 1
+
+ admin:
+ image: mailu/admin:{{ version }}
+ env_file: {{ env }}
+ {% if not admin_enabled %}
+ ports:
+ - 127.0.0.1:8080:80
+ {% endif %}
+ volumes:
+ - "{{ root }}/data:/data"
+ - "{{ root }}/dkim:/dkim"
+ deploy:
+ replicas: 1
+
+ imap:
+ image: mailu/dovecot:{{ version }}
+ env_file: {{ env }}
+ environment:
+ # Default to 10.0.1.0/24
+ - POD_ADDRESS_RANGE={{ subnet }}
+ volumes:
+ - "{{ root }}/mail:/mail"
+ - "{{ root }}/overrides:/overrides"
+ deploy:
+ replicas: 1
+
+ smtp:
+ image: mailu/postfix:{{ version }}
+ env_file: {{ env }}
+ environment:
+ - POD_ADDRESS_RANGE={{ subnet }}
+ volumes:
+ - "{{ root }}/overrides:/overrides"
+ deploy:
+ replicas: 1
+
+ # Optional services
+ {% if antispam_enabled %}
+ antispam:
+ image: mailu/rspamd:{{ version }}
+ env_file: {{ env }}
+ environment:
+ - POD_ADDRESS_RANGE={{ subnet }}
+ volumes:
+ - "{{ root }}/filter:/var/lib/rspamd"
+ - "{{ root }}/dkim:/dkim"
+ - "{{ root }}/overrides/rspamd:/etc/rspamd/override.d"
+ deploy:
+ replicas: 1
+ {% endif %}
+
+ {% if antivirus_enabled %}
+ antivirus:
+ image: mailu/clamav:{{ version }}
+ env_file: {{ env }}
+ volumes:
+ - "{{ root }}/filter:/data"
+ deploy:
+ replicas: 1
+ {% endif %}
+
+ {% if webdav_enabled %}
+ webdav:
+ image: mailu/none:{{ version }}
+ env_file: {{ env }}
+ volumes:
+ - "{{ root }}/dav:/data"
+ deploy:
+ replicas: 1
+ {% endif %}
+
+ {% if fetchmail_enabled %}
+ fetchmail:
+ image: mailu/fetchmail:{{ version }}
+ env_file: {{ env }}
+ volumes:
+ - "{{ root }}/data:/data"
+ deploy:
+ replicas: 1
+ {% endif %}
+
+ {% if webmail_type != 'none' %}
+ webmail:
+ image: mailu/roundcube:{{ version }}
+ env_file: {{ env }}
+ volumes:
+ - "{{ root }}/webmail:/data"
+ deploy:
+ replicas: 1
+ {% endif %}
+
+networks:
+ default:
+ driver: overlay
+ ipam:
+ driver: default
+ config:
+ - subnet: {{ subnet }}
diff --git a/setup/flavors/stack/mailu.env b/setup/flavors/stack/mailu.env
new file mode 120000
index 00000000..7123102b
--- /dev/null
+++ b/setup/flavors/stack/mailu.env
@@ -0,0 +1 @@
+../compose/mailu.env
\ No newline at end of file
diff --git a/setup/flavors/stack/setup.html b/setup/flavors/stack/setup.html
new file mode 100644
index 00000000..d68a6422
--- /dev/null
+++ b/setup/flavors/stack/setup.html
@@ -0,0 +1,60 @@
+{% import "macros.html" as macros %}
+
+{% call macros.panel("info", "Step 1 - Download your configuration files") %}
+Docker Stack expects a project file, named docker-compose.yml
+in a project directory. First create your project directory.
+
+mkdir -p /{{ root }}/{redis,certs,data,dkim,mail,overrides/rspamd,filter,dav,webmail}
+
+
+Then download the project file. A side configuration file makes it easier
+to read and check the configuration variables generated by the wizard.
+
+cd {{ root }}
+curl {{ url_for('.file', uid=uid, filepath='docker-compose.yml', _external=True) }} > docker-compose.yml
+curl {{ url_for('.file', uid=uid, filepath='mailu.env', _external=True) }} > mailu.env
+
+{% endcall %}
+
+
+{% call macros.panel("info", "Step 2 - Review the configuration") %}
+We did not insert any malicious code on purpose in the configurations we
+distribute, but your download could have been intercepted, or our wizard
+website could have been compromised, so make sure you check the configuration
+files before going any further.
+
+When you are done checking them, check them one last time.
+{% endcall %}
+
+{% call macros.panel("info", "Step 3 - Deploy docker stack") %}
+To deploy the docker stack use the following commands. For more information about setting up docker swarm nodes read the
+ docker documentation
+
+cd {{ root }}
+docker swarm init
+docker stack deploy -c docker-compose.yml mailu
+
+
+In the docker stack deploy command, mailu is the app name. Feel free to change it.
+In order to display the running container you can use
+docker ps
+or
+docker stack ps --no-trunc mailu
+Command for removing docker stack is
+docker stack rm mailu
+
+Before you can use Mailu, you must create the primary administrator user account. This should be {{ postmaster }}@{{ domain }}. Use the following command, changing PASSWORD to your liking:
+
+docker exec $(docker ps | grep admin | cut -d ' ' -f1) python manage.py admin {{ postmaster }} {{ domain }} PASSWORD
+
+
+Login to the admin interface to change the password for a safe one, at
+{% if admin_enabled %}
+one of the hostnames
+{{ hostnames.split(',')[0] }}{{ admin_path }} .
+{% else %}
+http://127.0.0.1:8080 (only directly from the host running docker).
+{% endif %}
+And choose the "Update password" option in the left menu.
+
+{% endcall %}
diff --git a/setup/server.py b/setup/server.py
index 108f5043..bfe5ef15 100644
--- a/setup/server.py
+++ b/setup/server.py
@@ -32,9 +32,11 @@ def secret(length=16):
def build_app(path):
+ #Hardcoded master as the only version for test purposes
versions = [
- version for version in os.listdir(path)
- if os.path.isdir(os.path.join(path, version))
+ # version for version in os.listdir(path)
+ # if os.path.isdir(os.path.join(path, version))
+ "master"
]
app.jinja_env.trim_blocks = True
@@ -63,6 +65,12 @@ def build_app(path):
def wizard():
return flask.render_template('wizard.html')
+ @bp.route("/submit_flavor", methods=["POST"])
+ def submit_flavor():
+ data = flask.request.form.copy()
+ steps = sorted(os.listdir(path + "/" + version + "/templates/steps/" + data["flavor"]))
+ return flask.render_template('wizard.html', flavor=data["flavor"], steps=steps)
+
@bp.route("/submit", methods=["POST"])
def submit():
data = flask.request.form.copy()
diff --git a/setup/templates/base.html b/setup/templates/base.html
index d40a4880..5be0b1eb 100644
--- a/setup/templates/base.html
+++ b/setup/templates/base.html
@@ -8,7 +8,7 @@
Mailu configuration
Version
-
+
{% for available in versions %}
{{ available }}
{% endfor %}
diff --git a/setup/templates/macros.html b/setup/templates/macros.html
index 579800d2..4af20c4e 100644
--- a/setup/templates/macros.html
+++ b/setup/templates/macros.html
@@ -9,10 +9,10 @@
{% endmacro %}
-{% macro radio(name, value, emph, text) %}
+{% macro radio(name, value, emph, text, current) %}
-
+
{% if emph %}
{{ emph }} ,
{% endif %}
diff --git a/setup/templates/steps/services.html b/setup/templates/steps/compose/02_services.html
similarity index 53%
rename from setup/templates/steps/services.html
rename to setup/templates/steps/compose/02_services.html
index e80b4ff4..7117c490 100644
--- a/setup/templates/steps/services.html
+++ b/setup/templates/steps/compose/02_services.html
@@ -3,31 +3,27 @@
interface, Web email clients (webmails), antispam, antivirus, etc. If you
wish to disable some of these features, you are free to do so.
-The admin interface is the main Mailu-specific bit, it provides tools to
-manage your email domains, users, etc.
-
-
-
Emails will be available through IMAP and POP3. You may also enable a Web
email client. These do add some complexity but provide an easier way of
accessing messages for beginner users.
+
Enable Web email client (and path to the Web email client)
-
+
+
+
+
+
+
+ {% for webmailtype in ["none", "roundcube", "rainloop"] %}
+ {{ webmailtype }}
+ {% endfor %}
+
-
@@ -38,15 +34,29 @@ also disable the antivirus if required (it does use aroung 1GB of ram).
-
- Enable the filtering service
+
+ Enable the spam filtering service
-
+
Enable the antivirus service
+
+
+
+ Enable the webdav service
+
+
+
+
+
+
+ Enable fetchmail
+
+
+
{% endcall %}
diff --git a/setup/templates/steps/compose/03_expose.html b/setup/templates/steps/compose/03_expose.html
new file mode 100644
index 00000000..df121c7d
--- /dev/null
+++ b/setup/templates/steps/compose/03_expose.html
@@ -0,0 +1,39 @@
+{% call macros.panel("info", "Step 4 - expose Mailu to the world") %}
+
A mail server must be exposed to the world to receive emails, send emails,
+and let users access their mailboxes. Mailu has some flexibility in the way
+you expose it to the world.
+
+
Among Mailu services, the front server is the one accepting connections,
+be it directly from the outside world, through a reverse proxy or in any
+complex configuration that you might want to setup. It needs to listen on some
+IP addresses in order to expose its public services. You must at least setup
+an IPv4 or an IPv6 address if you wish to access Mailu.
+
+
Warning You must use specific addresses, please
+avoid generic all-interfaces addresses like 0.0.0.0
or ::
.
+
+
+ IPv4 listen address
+
+
+
+
+
+ IPv6 listen address
+
+
+
+
+
You server will be available under a main hostname but may expose multiple public
+hostnames. Every e-mail domain that points to this server must have one of the
+hostnames in its MX
record. Hostnames must be coma-separated.
+
+
+ Public hostnames
+
+
+
+{% endcall %}
diff --git a/setup/templates/steps/config.html b/setup/templates/steps/config.html
new file mode 100644
index 00000000..88c17597
--- /dev/null
+++ b/setup/templates/steps/config.html
@@ -0,0 +1,78 @@
+{% call macros.panel("info", "Step 2 - Initial configuration") %}
+
Before starting some variables must be set
+
+
+ Root path:
+
+
+
+
+
In the next sections we need to set the postmaster address. This is a combination from the postmaster local part and the main mail domain .
+The main mail domain is also used as "server display name". This is the way the SMTP server identifies himself when connecting to others.
+The Postmaster will get an e-mail address <postmaster>@<main_domain>. This address will receive the DMARC "rua" and "ruf" reports.
+Or in plain english: if receivers start to classify your mail as spam, this postmaster will be informed.
+
+
+
+ Main mail domain and server display name.
+
+
+
+
+
+
+ Postmaster local part
+
+
+
+
+ Choose how you wish to handle security (TLS) certificates
+
+
+ {% for tlsflavor in ["letsencrypt", "cert", "notls", "mail", "mail-letsencrypt"] %}
+ {{ tlsflavor }}
+ {% endfor %}
+
+
+
+
+
+
+
+
+ Opt-out of statistics
+
+
+
+
+ Website name
+
+
+
+
+ Linked Website URL
+
+
+
+
+
The admin interface is the main Mailu-specific bit, it provides tools to
+manage your email domains, users, etc.
+
+
+
+{% endcall %}
diff --git a/setup/templates/steps/expose.html b/setup/templates/steps/expose.html
deleted file mode 100644
index 665b08a2..00000000
--- a/setup/templates/steps/expose.html
+++ /dev/null
@@ -1,33 +0,0 @@
-{% call macros.panel("info", "Step 2 - expose Mailu to the world") %}
-
A mail server must be exposed to the world to receive emails, send emails,
-and let users access their mailboxes. Mailu has some flexibility in the way
-you expose it to the world.
-
-
Among Mailu services, the front server is the one accepting connections,
-be it directly from the outside world, through a reverse proxy or in any
-complex configuration that you might want to setup. It needs to listen on some
-IP addresses in order to expose its public services. You must at least setup
-an IPv4 or an IPv6 address if you wish to access Mailu.
-
-
Warning You must use specific addresses, please
-avoid generic all-interfaces addresses like 0.0.0.0
or ::
.
-
-
- IPv4 listen address
-
-
-
-
- IPv6 listen address
-
-
-
-
You server will be available under a main hostname but may expose multiple public
-hostnames. Every e-mail domain that points to this server must have one of the
-hostnames in its MX
record. Hostnames must be coma-separated.
-
-
- Public hostnames
-
-
-{% endcall %}
diff --git a/setup/templates/steps/flavor.html b/setup/templates/steps/flavor.html
index 66da0757..64aa0158 100644
--- a/setup/templates/steps/flavor.html
+++ b/setup/templates/steps/flavor.html
@@ -7,10 +7,10 @@ developpers, will mostly cover Compose and Stack, while other flavors are
maintained by specific contributors.
- {{ macros.radio("flavor", "compose", "Compose", "simply using Docker Compose manager") }}
- {{ macros.radio("flavor", "stack", "Stack", "using stack deployments in a Swarm cluster") }}
- {{ macros.radio("flavor", "rancher", "Rancher", "on top of the Rancher container manager") }}
- {{ macros.radio("flavor", "kubernetes", "Kubernetes", "on top of the Kubernetes container manager") }}
+ {{ macros.radio("flavor", "compose", "Compose", "simply using Docker Compose manager", flavor) }}
+ {{ macros.radio("flavor", "stack", "Stack", "using stack deployments in a Swarm cluster", flavor) }}
+ {{ macros.radio("flavor", "rancher", "Rancher", "on top of the Rancher container manager", flavor) }}
+ {{ macros.radio("flavor", "kubernetes", "Kubernetes", "on top of the Kubernetes container manager", flavor) }}
{% endcall %}
diff --git a/setup/templates/steps/optional.html b/setup/templates/steps/optional.html
deleted file mode 100644
index b7878b23..00000000
--- a/setup/templates/steps/optional.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% call macros.panel("info", "Step 4 - enable optional features") %}
-
Mailu also comes with less common optional features that you might wish
-to enable.
-
-
The DAV service enables contacts and calendar storage through Mailu,
-it is especially userful when synchronizing your desktop and mobile devices.
-
-
-
-{% endcall %}
diff --git a/setup/templates/steps/stack/02_services.html b/setup/templates/steps/stack/02_services.html
new file mode 100644
index 00000000..7117c490
--- /dev/null
+++ b/setup/templates/steps/stack/02_services.html
@@ -0,0 +1,62 @@
+{% call macros.panel("info", "Step 3 - pick some features") %}
+
Mailu comes with multiple base features, including a specific admin
+interface, Web email clients (webmails), antispam, antivirus, etc. If you
+wish to disable some of these features, you are free to do so.
+
+
Emails will be available through IMAP and POP3. You may also enable a Web
+email client. These do add some complexity but provide an easier way of
+accessing messages for beginner users.
+
+
+
+
+
Email filtering is a really important features. You can still disable it, which
+will prevent Mailu from doing spam filtering, virus filtering, and from applying
+white and blacklists that you may configure in the admin interface. You may
+also disable the antivirus if required (it does use aroung 1GB of ram).
+
+
+
+
+ Enable the spam filtering service
+
+
+
+
+
+ Enable the antivirus service
+
+
+
+
+
+
+ Enable the webdav service
+
+
+
+
+
+
+ Enable fetchmail
+
+
+
+{% endcall %}
diff --git a/setup/templates/steps/stack/03_expose.html b/setup/templates/steps/stack/03_expose.html
new file mode 100644
index 00000000..a9cffc1c
--- /dev/null
+++ b/setup/templates/steps/stack/03_expose.html
@@ -0,0 +1,21 @@
+{% call macros.panel("info", "Step 4 - expose Mailu to the world") %}
+
A mail server must be exposed to the world to receive emails, send emails,
+and let users access their mailboxes. Mailu has some flexibility in the way
+you expose it to the world.
+
+
+ Subnet
+
+
+
+
You server will be available under a main hostname but may expose multiple public
+hostnames. Every e-mail domain that points to this server must have one of the
+hostnames in its MX
record. Hostnames must be coma-separated.
+
+
+ Public hostnames
+
+
+
+{% endcall %}
diff --git a/setup/templates/wizard.html b/setup/templates/wizard.html
index da9d5134..05de5a5c 100644
--- a/setup/templates/wizard.html
+++ b/setup/templates/wizard.html
@@ -8,12 +8,18 @@
ready when using this wizard.
{% endcall %}
-
+ {% if flavor %}
+
{% endblock %}
diff --git a/webmails/rainloop/Dockerfile b/webmails/rainloop/Dockerfile
index 889c8486..5d751716 100644
--- a/webmails/rainloop/Dockerfile
+++ b/webmails/rainloop/Dockerfile
@@ -3,7 +3,7 @@ FROM php:7.2-apache
ENV RAINLOOP_URL https://github.com/RainLoop/rainloop-webmail/releases/download/v1.12.1/rainloop-community-1.12.1.zip
RUN apt-get update && apt-get install -y \
- unzip python3 python3-jinja2 \
+ unzip python3 python3-jinja2 curl \
&& rm -rf /var/www/html/ \
&& mkdir /var/www/html \
&& cd /var/www/html \
@@ -29,3 +29,5 @@ EXPOSE 80/tcp
VOLUME ["/data"]
CMD /start.py
+
+HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1
diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile
index 50a58a4f..6250e6df 100644
--- a/webmails/roundcube/Dockerfile
+++ b/webmails/roundcube/Dockerfile
@@ -3,7 +3,7 @@ FROM php:7.2-apache
ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.3.7/roundcubemail-1.3.7-complete.tar.gz
RUN apt-get update && apt-get install -y \
- zlib1g-dev \
+ zlib1g-dev curl \
&& docker-php-ext-install zip \
&& echo date.timezone=UTC > /usr/local/etc/php/conf.d/timezone.ini \
&& rm -rf /var/www/html/ \
@@ -28,3 +28,5 @@ EXPOSE 80/tcp
VOLUME ["/data"]
CMD ["/start.sh"]
+
+HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1