From fcad52b1454aeeb5b11d64fe0186f644922f96b2 Mon Sep 17 00:00:00 2001 From: kaiyou Date: Thu, 27 Sep 2018 22:45:16 +0200 Subject: [PATCH 01/39] Implement a start date filter for autoreply, fixes #362 --- core/admin/mailu/models.py | 2 ++ core/admin/mailu/ui/forms.py | 1 + core/admin/mailu/ui/templates/user/reply.html | 7 ++++-- .../migrations/versions/3b281286c7bd_.py | 24 +++++++++++++++++++ core/dovecot/conf/pigeonhole-sieve.dict | 8 +++++++ core/dovecot/sieve/before.sieve | 1 + 6 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 core/admin/migrations/versions/3b281286c7bd_.py diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 71c5f4d7..1be4c8e6 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -249,6 +249,8 @@ class User(Base, Email): reply_enabled = db.Column(db.Boolean(), nullable=False, default=False) reply_subject = db.Column(db.String(255), nullable=True, default=None) reply_body = db.Column(db.Text(), nullable=True, default=None) + reply_startdate = db.Column(db.Date, nullable=False, + default=date(1900, 1, 1)) reply_enddate = db.Column(db.Date, nullable=False, default=date(2999, 12, 31)) diff --git a/core/admin/mailu/ui/forms.py b/core/admin/mailu/ui/forms.py index 326d721b..4f7a30ae 100644 --- a/core/admin/mailu/ui/forms.py +++ b/core/admin/mailu/ui/forms.py @@ -117,6 +117,7 @@ class UserReplyForm(flask_wtf.FlaskForm): reply_subject = fields.StringField(_('Reply subject')) reply_body = fields.StringField(_('Reply body'), widget=widgets.TextArea()) + reply_startdate = fields.html5.DateField(_('Start of vacation')) reply_enddate = fields.html5.DateField(_('End of vacation')) submit = fields.SubmitField(_('Update')) diff --git a/core/admin/mailu/ui/templates/user/reply.html b/core/admin/mailu/ui/templates/user/reply.html index 7906bc42..7225a178 100644 --- a/core/admin/mailu/ui/templates/user/reply.html +++ b/core/admin/mailu/ui/templates/user/reply.html @@ -13,14 +13,17 @@
{{ form.hidden_tag() }} {{ macros.form_field(form.reply_enabled, - onchange="if(this.checked){$('#reply_subject,#reply_body,#reply_enddate').removeAttr('readonly')} + onchange="if(this.checked){$('#reply_subject,#reply_body,#reply_enddate,#reply_startdate').removeAttr('readonly')} else{$('#reply_subject,#reply_body,#reply_enddate').attr('readonly', '')}") }} {{ macros.form_field(form.reply_subject, **{("rw" if user.reply_enabled else "readonly"): ""}) }} {{ macros.form_field(form.reply_body, rows=10, **{("rw" if user.reply_enabled else "readonly"): ""}) }} {{ macros.form_field(form.reply_enddate, - **{("rw" if user.reply_enabled else "readonly"): ""}) }} + **{("rw" if user.reply_enabled else "readonly"): ""}) }} + {{ macros.form_field(form.reply_startdate, + **{("rw" if user.reply_enabled else "readonly"): ""}) }} + {{ macros.form_field(form.submit) }}
{% endcall %} diff --git a/core/admin/migrations/versions/3b281286c7bd_.py b/core/admin/migrations/versions/3b281286c7bd_.py new file mode 100644 index 00000000..78e44a4c --- /dev/null +++ b/core/admin/migrations/versions/3b281286c7bd_.py @@ -0,0 +1,24 @@ +""" Add a start day for vacations + +Revision ID: 3b281286c7bd +Revises: 049fed905da7 +Create Date: 2018-09-27 22:20:08.158553 + +""" + +revision = '3b281286c7bd' +down_revision = '049fed905da7' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + with op.batch_alter_table('user') as batch: + batch.add_column(sa.Column('reply_startdate', sa.Date(), nullable=False, + server_default="1900-01-01")) + + +def downgrade(): + with op.batch_alter_table('user') as batch: + batch.drop_column('reply_startdate') diff --git a/core/dovecot/conf/pigeonhole-sieve.dict b/core/dovecot/conf/pigeonhole-sieve.dict index 917fce83..604371a8 100644 --- a/core/dovecot/conf/pigeonhole-sieve.dict +++ b/core/dovecot/conf/pigeonhole-sieve.dict @@ -41,3 +41,11 @@ map { username_field = email value_field = reply_enddate } + +map { + pattern = priv/reply_startdate + table = user + username_field = email + value_field = reply_startdate +} + diff --git a/core/dovecot/sieve/before.sieve b/core/dovecot/sieve/before.sieve index 6ebc20c5..81d20f30 100644 --- a/core/dovecot/sieve/before.sieve +++ b/core/dovecot/sieve/before.sieve @@ -34,6 +34,7 @@ if exists "X-Virus" { } if allof (string :is "${extdata.reply_enabled}" "1", + currentdate :value "ge" "date" "${extdata.reply_startdate}", currentdate :value "le" "date" "${extdata.reply_enddate}") { vacation :days 1 :subject "${extdata.reply_subject}" "${extdata.reply_body}"; From 11a8e49f059c4eb71a8f931edcbfa238d90873a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Tue, 16 Oct 2018 11:09:42 +0300 Subject: [PATCH 02/39] Compose file upgrade and define more variables for setup --- setup/flavors/compose/docker-compose.yml | 38 ++++++++++++------------ setup/flavors/compose/mailu.env | 16 +++++----- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index fcf0c092..a82817af 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -2,7 +2,7 @@ # This file is auto-generated by the Mailu configuration wizard. # Please read the documentation before attempting any change. -version: '2' +version: '3.7' services: @@ -11,7 +11,7 @@ services: image: redis:alpine restart: always volumes: - - "$ROOT/redis:/data" + - "{{ root }}/redis:/data" # Core services front: @@ -24,15 +24,15 @@ services: 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" + - "{{ root }}/certs:/certs" {% endif %} admin: @@ -44,8 +44,8 @@ services: - 127.0.0.1:8080:80 {% endif %} volumes: - - "$ROOT/data:/data" - - "$ROOT/dkim:/dkim" + - "{{ root }}/data:/data" + - "{{ root }}/dkim:/dkim" depends_on: - redis @@ -54,9 +54,9 @@ services: restart: always env_file: {{ env }} volumes: - - "$ROOT/data:/data" - - "$ROOT/mail:/mail" - - "$ROOT/overrides:/overrides" + - "{{ root }}/data:/data" + - "{{ root }}/mail:/mail" + - "{{ root }}/overrides:/overrides" depends_on: - front @@ -65,8 +65,8 @@ services: restart: always env_file: {{ env }} volumes: - - "$ROOT/data:/data" - - "$ROOT/overrides:/overrides" + - "{{ root }}/data:/data" + - "{{ root }}/overrides:/overrides" depends_on: - front @@ -77,9 +77,9 @@ services: 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 %} @@ -90,7 +90,7 @@ services: restart: always env_file: {{ env }} volumes: - - "$ROOT/filter:/data" + - "{{ root }}/filter:/data" {% endif %} {% if enable_webdav %} @@ -99,7 +99,7 @@ services: restart: always env_file: {{ env }} volumes: - - "$ROOT/dav:/data" + - "{{ root }}/dav:/data" {% endif %} {% if enable_fetchmail %} @@ -108,7 +108,7 @@ services: restart: always env_file: {{ env }} volumes: - - "$ROOT/data:/data" + - "{{ root }}/data:/data" {% endif %} # Webmail @@ -118,7 +118,7 @@ services: restart: always 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..2de771f3 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -9,14 +9,16 @@ ################################### # 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=/mailu # 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=127.0.0.1 +# PUBLIC_IPV6=::1 # Mail address of the postmaster POSTMASTER={{ postmaster }} @@ -75,16 +77,16 @@ DOMAIN_REGISTRATION=true ################################### # Path to the admin interface if enabled -WEB_ADMIN=/admin +WEB_ADMIN={{ admin_path }} # Path to the webmail if enabled -WEB_WEBMAIL=/webmail +WEB_WEBMAIL={{ webmail_path }} # Website name -SITENAME=Mailu +SITENAME={{ site_name }{ # Linked Website URL -WEBSITE=https://mailu.io +WEBSITE={{ website }} {% if recaptcha_public_key and recaptcha_private_key %} # Registration reCaptcha settings (warning, this has some privacy impact) From 0d164486b45b194de81905089b37a4557a828a8f Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Tue, 16 Oct 2018 12:34:55 +0300 Subject: [PATCH 03/39] docker-compose variables and setup --- setup/Dockerfile | 4 +++- setup/docker-compose.yml | 1 + setup/flavors/compose/docker-compose.yml | 2 +- setup/flavors/compose/mailu.env | 8 ++++---- setup/flavors/compose/setup.html | 6 +++--- setup/server.py | 6 ++++-- setup/templates/steps/expose.html | 4 ++-- setup/templates/steps/root.html | 8 ++++++++ setup/templates/wizard.html | 1 + 9 files changed, 27 insertions(+), 13 deletions(-) create mode 100644 setup/templates/steps/root.html diff --git a/setup/Dockerfile b/setup/Dockerfile index 1fc808f1..c970e57d 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -10,8 +10,10 @@ RUN apk add --no-cache git \ 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 diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 9288bb7e..30966167 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -10,4 +10,5 @@ services: image: mailu/setup ports: - "80:80" + build: . diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index a82817af..3dcfa5a2 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -24,7 +24,7 @@ services: ports: {% for port in (80, 443, 25, 465, 587, 110, 995, 143, 993) %} {% if bind4 %} - - "{{ bind4}}:{{ port }}:{{ port }}" + - "{{ bind4 }}:{{ port }}:{{ port }}" {% endif %} {% if bind6 %} - "{{ bind6 }}:{{ port }}:{{ port }}" diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 2de771f3..1512e75b 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -10,15 +10,15 @@ # Set this to the path where Mailu data and configuration is stored # This variable is now set directly in `docker-compose.yml by the setup utility -# ROOT=/mailu +# ROOT= {{ root }} # Set to a randomly generated 16 bytes string SECRET_KEY={{ secret(16) }} # Address where listening ports should bind # This variables are now set directly in `docker-compose.yml by the setup utility -# PUBLIC_IPV4=127.0.0.1 -# PUBLIC_IPV6=::1 +# PUBLIC_IPV4= {{ bind4 }} (default: 127.0.0.1) +# PUBLIC_IPV6= {{ bind6 }} (default: ::1) # Mail address of the postmaster POSTMASTER={{ postmaster }} @@ -83,7 +83,7 @@ WEB_ADMIN={{ admin_path }} WEB_WEBMAIL={{ webmail_path }} # Website name -SITENAME={{ site_name }{ +SITENAME={{ site_name }} # Linked Website URL WEBSITE={{ website }} diff --git a/setup/flavors/compose/setup.html b/setup/flavors/compose/setup.html index e4506e6d..3c190c9c 100644 --- a/setup/flavors/compose/setup.html +++ b/setup/flavors/compose/setup.html @@ -4,13 +4,13 @@

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
+
cd {{ root }}
 wget {{ url_for('.file', uid=uid, filepath='docker-compose.yml', _external=True) }}
 wget {{ url_for('.file', uid=uid, filepath='mailu.env', _external=True) }}
 
@@ -30,7 +30,7 @@ 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
 
{% endcall %} diff --git a/setup/server.py b/setup/server.py index 108f5043..ddeafd90 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 diff --git a/setup/templates/steps/expose.html b/setup/templates/steps/expose.html index 665b08a2..372ebddc 100644 --- a/setup/templates/steps/expose.html +++ b/setup/templates/steps/expose.html @@ -14,12 +14,12 @@ avoid generic all-interfaces addresses like 0.0.0.0 or :: - +
- +

You server will be available under a main hostname but may expose multiple public diff --git a/setup/templates/steps/root.html b/setup/templates/steps/root.html new file mode 100644 index 00000000..f32c2250 --- /dev/null +++ b/setup/templates/steps/root.html @@ -0,0 +1,8 @@ +{% call macros.panel("info", "Step 0 - Set root path") %} +

Before starting root path must be set

+ +
+ + +
+{% endcall %} diff --git a/setup/templates/wizard.html b/setup/templates/wizard.html index da9d5134..bbebe569 100644 --- a/setup/templates/wizard.html +++ b/setup/templates/wizard.html @@ -9,6 +9,7 @@ {% endcall %}
+ {% include "steps/root.html" %} {% include "steps/flavor.html" %} {% include "steps/expose.html" %} {% include "steps/services.html" %} From e8dee22ecfc8836f7d0a9ec56b3d68fba582b718 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Tue, 16 Oct 2018 16:12:42 +0300 Subject: [PATCH 04/39] Added vars and fixed naming use --- setup/flavors/compose/docker-compose.yml | 10 ++-- setup/flavors/compose/mailu.env | 32 +++++++++++-- setup/templates/steps/initial-config.html | 58 +++++++++++++++++++++++ setup/templates/steps/root.html | 8 ---- setup/templates/steps/services.html | 15 ++++-- setup/templates/wizard.html | 4 +- 6 files changed, 105 insertions(+), 22 deletions(-) create mode 100644 setup/templates/steps/initial-config.html delete mode 100644 setup/templates/steps/root.html diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index 3dcfa5a2..bf6c2db8 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -71,7 +71,7 @@ services: - front # Optional services - {% if enable_antispam %} + {% if antispam_enabled %} antispam: image: mailu/rspamd:{{ version }} restart: always @@ -84,7 +84,7 @@ services: - front {% endif %} - {% if enable_antivirus %} + {% if antivirus_enabled %} antivirus: image: mailu/clamav:{{ version }} restart: always @@ -93,9 +93,9 @@ services: - "{{ root }}/filter:/data" {% endif %} - {% if enable_webdav %} + {% if webdav_enabled %} webdav: - image: mailu/radivale:{{ version }} + image: mailu/radicale:{{ version }} restart: always env_file: {{ env }} volumes: @@ -112,7 +112,7 @@ services: {% endif %} # Webmail - {% if enable_webmail %} + {% if webmail_enabled %} webmail: image: mailu/{{ webmail }}:{{ version }} restart: always diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 1512e75b..4f470533 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -10,7 +10,7 @@ # Set this to the path where Mailu data and configuration is stored # This variable is now set directly in `docker-compose.yml by the setup utility -# ROOT= {{ root }} +# ROOT={{ root }} # Set to a randomly generated 16 bytes string SECRET_KEY={{ secret(16) }} @@ -20,8 +20,14 @@ SECRET_KEY={{ secret(16) }} # PUBLIC_IPV4= {{ bind4 }} (default: 127.0.0.1) # PUBLIC_IPV6= {{ bind6 }} (default: ::1) +# Main mail domain +# DOMAIN={{ domain }} + # Mail address of the postmaster -POSTMASTER={{ postmaster }} +POSTMASTER={{ postmaster or 'admin'}} + +#Chose how secure connections will behave: +#TLS_FLAVOR={{ tls_flavor }} # Hostnames for this server, separated with comas HOSTNAMES={{ hostnames }} @@ -30,7 +36,27 @@ HOSTNAMES={{ hostnames }} AUTH_RATELIMIT={{ auth_ratelimit }} # Opt-out of statistics, replace with "True" to opt out -DISABLE_STATISTICS={{ disable_statistics }} +DISABLE_STATISTICS={{ disable_statistics or 'False' }} + +################################### +# Optional features +################################### + +#Expose the admin interface +ADMIN={{ admin_enabled or 'false' }} + +#Chose which webmail to run if any +#WEBMAIL_ENABLED={{ webmail_enabled or 'false' }} +WEBMAIL={{ webmail_type or 'none' }} + +#Antivirus solution +ANTIVIRUS={{ antivirus_enabled or 'none' }} + +#Antispam solution +#ANTISPAM={{ antispam_enabled or 'none'}} + +#Dav server implementation +WEBDAV={{ webdav_enabled or 'none' }} ################################### # Server behavior diff --git a/setup/templates/steps/initial-config.html b/setup/templates/steps/initial-config.html new file mode 100644 index 00000000..d71d2971 --- /dev/null +++ b/setup/templates/steps/initial-config.html @@ -0,0 +1,58 @@ +{% call macros.panel("info", "Step 0 - Initial configuration") %} +

Before starting some variables must be st

+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +{% endcall %} diff --git a/setup/templates/steps/root.html b/setup/templates/steps/root.html deleted file mode 100644 index f32c2250..00000000 --- a/setup/templates/steps/root.html +++ /dev/null @@ -1,8 +0,0 @@ -{% call macros.panel("info", "Step 0 - Set root path") %} -

Before starting root path must be set

- -
- - -
-{% endcall %} diff --git a/setup/templates/steps/services.html b/setup/templates/steps/services.html index e80b4ff4..e6ee88aa 100644 --- a/setup/templates/steps/services.html +++ b/setup/templates/steps/services.html @@ -9,7 +9,7 @@ manage your email domains, users, etc.

-
+
@@ -21,7 +21,7 @@ accessing messages for beginner users.

-
+

@@ -38,15 +38,22 @@ also disable the antivirus if required (it does use aroung 1GB of ram).

+
+ +
+ {% endcall %} diff --git a/setup/templates/wizard.html b/setup/templates/wizard.html index bbebe569..5a15af6f 100644 --- a/setup/templates/wizard.html +++ b/setup/templates/wizard.html @@ -9,11 +9,11 @@ {% endcall %} - {% include "steps/root.html" %} + {% include "steps/initial-config.html" %} {% include "steps/flavor.html" %} {% include "steps/expose.html" %} {% include "steps/services.html" %} - {% include "steps/optional.html" %} + From b9ecc0ccc6380c51dfd032397524e8c0d9ab4073 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Tue, 16 Oct 2018 18:03:59 +0300 Subject: [PATCH 05/39] Added minor changes --- setup/flavors/compose/docker-compose.yml | 10 ++++----- setup/flavors/compose/mailu.env | 11 +++++----- setup/templates/steps/initial-config.html | 25 ++++++++++++----------- setup/templates/steps/services.html | 11 ++++++++-- 4 files changed, 33 insertions(+), 24 deletions(-) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index bf6c2db8..83a46169 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -19,8 +19,8 @@ services: restart: always env_file: {{ env }} env: - - TLS_FLAVOR={{ tls_flavor or 'letsencrypt' }} - - ADMIN={{ expose_admin or 'no' }} + - TLS_FLAVOR={{ tls_flavor }} + - ADMIN={{ admin_enabled or 'no' }} ports: {% for port in (80, 443, 25, 465, 587, 110, 995, 143, 993) %} {% if bind4 %} @@ -39,7 +39,7 @@ services: 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 %} @@ -102,7 +102,7 @@ services: - "{{ root }}/dav:/data" {% endif %} - {% if enable_fetchmail %} + {% if fetchmail_enabled %} fetchmail: image: mailu/fetchmail:{{ version }} restart: always @@ -114,7 +114,7 @@ services: # Webmail {% if webmail_enabled %} webmail: - image: mailu/{{ webmail }}:{{ version }} + image: mailu/{{ webmail_type }}:{{ version }} restart: always env_file: {{ env }} volumes: diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 4f470533..b1cded1c 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -33,7 +33,8 @@ POSTMASTER={{ postmaster or 'admin'}} HOSTNAMES={{ hostnames }} # Authentication rate limit (per source IP address) -AUTH_RATELIMIT={{ auth_ratelimit }} +AUTH_RATELIMIT={% if auth_ratelimit_pm %}{{ auth_ratelimit_pm }}/minute;{% endif %} +{% if auth_ratelimit_ph %}{{ auth_ratelimit_ph }}/hour{% endif %} # Opt-out of statistics, replace with "True" to opt out DISABLE_STATISTICS={{ disable_statistics or 'False' }} @@ -43,20 +44,20 @@ DISABLE_STATISTICS={{ disable_statistics or 'False' }} ################################### #Expose the admin interface -ADMIN={{ admin_enabled or 'false' }} +#ADMIN={{ admin_enabled or 'false' }} #Chose which webmail to run if any #WEBMAIL_ENABLED={{ webmail_enabled or 'false' }} -WEBMAIL={{ webmail_type or 'none' }} +#WEBMAIL={{ webmail_type or 'none' }} #Antivirus solution -ANTIVIRUS={{ antivirus_enabled or 'none' }} +#ANTIVIRUS={{ antivirus_enabled or 'none' }} #Antispam solution #ANTISPAM={{ antispam_enabled or 'none'}} #Dav server implementation -WEBDAV={{ webdav_enabled or 'none' }} +#WEBDAV={{ webdav_enabled or 'none' }} ################################### # Server behavior diff --git a/setup/templates/steps/initial-config.html b/setup/templates/steps/initial-config.html index d71d2971..c16d4c13 100644 --- a/setup/templates/steps/initial-config.html +++ b/setup/templates/steps/initial-config.html @@ -3,7 +3,7 @@
- +
@@ -11,9 +11,16 @@
+
+ +
+
- +
@@ -28,7 +35,8 @@
- +

/minute; + /hour

@@ -40,19 +48,12 @@
- +
- -
- -
- +
{% endcall %} diff --git a/setup/templates/steps/services.html b/setup/templates/steps/services.html index e6ee88aa..ed529c83 100644 --- a/setup/templates/steps/services.html +++ b/setup/templates/steps/services.html @@ -38,8 +38,8 @@ also disable the antivirus if required (it does use aroung 1GB of ram).

@@ -56,4 +56,11 @@ also disable the antivirus if required (it does use aroung 1GB of ram).

+
+ +
+ {% endcall %} From 5ada669f43b26b35c7f8ca2eab89fd8d2d5e3611 Mon Sep 17 00:00:00 2001 From: kaiyou Date: Tue, 16 Oct 2018 20:38:18 +0200 Subject: [PATCH 06/39] Rebase reply startdate on master --- core/admin/mailu/internal/templates/default.sieve | 2 +- core/admin/mailu/models.py | 2 +- core/admin/migrations/versions/3b281286c7bd_.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/admin/mailu/internal/templates/default.sieve b/core/admin/mailu/internal/templates/default.sieve index 214b8125..d771ee99 100644 --- a/core/admin/mailu/internal/templates/default.sieve +++ b/core/admin/mailu/internal/templates/default.sieve @@ -32,6 +32,6 @@ if exists "X-Virus" { stop; } -{% if user.reply_active and %} +{% if user.reply_active %} vacation :days 1 :subject "{{ user.reply_subject }}" "{{ user.reply_body }}"; {% endif %} diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index bb8cdc94..f7c3349d 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -280,7 +280,7 @@ class User(Base, Email): @property def reply_active(self): - now = datetime.datetime.now() + now = date.today() return ( self.reply_enabled and self.reply_startdate < now and diff --git a/core/admin/migrations/versions/3b281286c7bd_.py b/core/admin/migrations/versions/3b281286c7bd_.py index 78e44a4c..57b5c327 100644 --- a/core/admin/migrations/versions/3b281286c7bd_.py +++ b/core/admin/migrations/versions/3b281286c7bd_.py @@ -1,13 +1,13 @@ """ Add a start day for vacations Revision ID: 3b281286c7bd -Revises: 049fed905da7 +Revises: 25fd6c7bcb4a Create Date: 2018-09-27 22:20:08.158553 """ revision = '3b281286c7bd' -down_revision = '049fed905da7' +down_revision = '25fd6c7bcb4a' from alembic import op import sqlalchemy as sa From 39272ab05c35d05366c35a8ebfd25e87ea7f41de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=C3=A4nger?= Date: Tue, 16 Oct 2018 21:38:12 +0200 Subject: [PATCH 07/39] add healthcheck for http services --- core/admin/Dockerfile | 4 +++- core/nginx/Dockerfile | 4 +++- docs/Dockerfile | 8 ++++++-- optional/radicale/Dockerfile | 4 +++- services/rspamd/Dockerfile | 4 +++- setup/Dockerfile | 4 +++- webmails/rainloop/Dockerfile | 4 +++- webmails/roundcube/Dockerfile | 4 +++- 8 files changed, 27 insertions(+), 9 deletions(-) diff --git a/core/admin/Dockerfile b/core/admin/Dockerfile index 2e637206..083bec80 100644 --- a/core/admin/Dockerfile +++ b/core/admin/Dockerfile @@ -4,7 +4,7 @@ RUN mkdir -p /app WORKDIR /app COPY requirements-prod.txt requirements.txt -RUN apk add --no-cache openssl \ +RUN apk add --no-cache openssl curl \ && apk add --no-cache --virtual build-dep openssl-dev libffi-dev python-dev build-base \ && pip install -r requirements.txt \ && apk del --no-cache build-dep @@ -20,3 +20,5 @@ EXPOSE 80/tcp VOLUME ["/data"] CMD ["/start.sh"] + +HEALTHCHECK CMD curl -f -L http://localhost/ui || exit 1 diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 1b61447a..87951c03 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -1,6 +1,6 @@ FROM alpine:3.8 -RUN apk add --no-cache certbot nginx nginx-mod-mail openssl \ +RUN apk add --no-cache certbot nginx nginx-mod-mail openssl curl \ python py-jinja2 py-requests-toolbelt py-pip \ && pip install --upgrade pip \ && pip install idna @@ -12,3 +12,5 @@ EXPOSE 80/tcp 443/tcp 110/tcp 143/tcp 465/tcp 587/tcp 993/tcp 995/tcp 25/tcp 100 VOLUME ["/certs"] CMD /start.py + +HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 diff --git a/docs/Dockerfile b/docs/Dockerfile index af481a27..b058e0e2 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -3,7 +3,7 @@ FROM python:3-alpine COPY requirements.txt /requirements.txt RUN pip install -r /requirements.txt \ - && apk add --no-cache nginx \ + && apk add --no-cache nginx curl \ && mkdir /run/nginx COPY ./nginx.conf /etc/nginx/conf.d/default.conf @@ -11,4 +11,8 @@ COPY . /docs RUN sphinx-build /docs /build -CMD nginx -g "daemon off;" \ No newline at end of file +EXPOSE 80/tcp + +CMD nginx -g "daemon off;" + +HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 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 7239ddaf..d87a64f5 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 ca-certificates py-pip \ +RUN apk add --no-cache python py-jinja2 rspamd rspamd-controller rspamd-proxy ca-certificates py-pip curl \ && pip install --upgrade pip \ && pip install tenacity @@ -17,3 +17,5 @@ EXPOSE 11332/tcp 11334/tcp VOLUME ["/var/lib/rspamd"] CMD /start.py + +HEALTHCHECK CMD curl -f -L http://localhost:11334/ || exit 1 diff --git a/setup/Dockerfile b/setup/Dockerfile index 1fc808f1..0da1eb7b 100644 --- a/setup/Dockerfile +++ b/setup/Dockerfile @@ -4,7 +4,7 @@ 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 @@ -16,3 +16,5 @@ 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/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 From 040c1e529ac293b26bccd5d1be86e52a9561bb2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=C3=A4nger?= Date: Tue, 16 Oct 2018 22:20:16 +0200 Subject: [PATCH 08/39] add healthcheck for antivirus --- optional/clamav/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/optional/clamav/Dockerfile b/optional/clamav/Dockerfile index a27c0eb2..fd5de38b 100644 --- a/optional/clamav/Dockerfile +++ b/optional/clamav/Dockerfile @@ -9,3 +9,5 @@ EXPOSE 3310/tcp VOLUME ["/data"] CMD ["/start.sh"] + +HEALTHCHECK CMD [ "$(echo PING | nc localhost 3310)" = "PONG" ] From f0f5cea5d1dba49d966d4e61d88e5dfae889c09a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=C3=A4nger?= Date: Tue, 16 Oct 2018 22:30:15 +0200 Subject: [PATCH 09/39] make antivirus-healthcheck more understandable --- optional/clamav/Dockerfile | 3 ++- optional/clamav/health.sh | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100755 optional/clamav/health.sh diff --git a/optional/clamav/Dockerfile b/optional/clamav/Dockerfile index fd5de38b..3a9bf4aa 100644 --- a/optional/clamav/Dockerfile +++ b/optional/clamav/Dockerfile @@ -4,10 +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 [ "$(echo PING | nc localhost 3310)" = "PONG" ] +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 From 8fa80c15894da57131cea00f8274737d37d8054f Mon Sep 17 00:00:00 2001 From: kaiyou Date: Tue, 16 Oct 2018 22:52:21 +0200 Subject: [PATCH 10/39] Support multiple docs versions --- docs/Dockerfile | 6 +++++- docs/_templates/page.html | 4 ---- docs/_templates/versions.html | 16 ++++++++++++++++ docs/conf.py | 8 +++++++- docs/docker-compose.yml | 21 +++++++++++++++++++++ 5 files changed, 49 insertions(+), 6 deletions(-) delete mode 100644 docs/_templates/page.html create mode 100644 docs/_templates/versions.html create mode 100644 docs/docker-compose.yml diff --git a/docs/Dockerfile b/docs/Dockerfile index af481a27..c1992f32 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -2,6 +2,9 @@ FROM python:3-alpine COPY requirements.txt /requirements.txt +ARG version=master +ENV VERSION=$version + RUN pip install -r /requirements.txt \ && apk add --no-cache nginx \ && mkdir /run/nginx @@ -9,6 +12,7 @@ RUN pip install -r /requirements.txt \ COPY ./nginx.conf /etc/nginx/conf.d/default.conf COPY . /docs -RUN sphinx-build /docs /build +RUN mkdir -p /build/$VERSION \ + && sphinx-build /docs /build/$VERSION CMD nginx -g "daemon off;" \ No newline at end of file diff --git a/docs/_templates/page.html b/docs/_templates/page.html deleted file mode 100644 index 97296793..00000000 --- a/docs/_templates/page.html +++ /dev/null @@ -1,4 +0,0 @@ -{%- extends "layout.html" %} -{% block body %} - {{ body|replace("VERSION_TAG", version) }} -{% endblock %} diff --git a/docs/_templates/versions.html b/docs/_templates/versions.html new file mode 100644 index 00000000..db4d332d --- /dev/null +++ b/docs/_templates/versions.html @@ -0,0 +1,16 @@ +
+ + Versions + v: {{ version }} + + +
+
+
{{ _('Versions') }}
+ {% for slug, url in versions %} +
{{ slug }}
+ {% endfor %} +
+
+
+ diff --git a/docs/conf.py b/docs/conf.py index f89b39fd..e86a7b9e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,6 +2,8 @@ # -*- coding: utf-8 -*- # +import os + extensions = ['sphinx.ext.imgmath', 'sphinx.ext.viewcode'] templates_path = ['_templates'] source_suffix = '.rst' @@ -33,6 +35,10 @@ html_context = { 'display_github': True, 'github_user': 'mailu', 'github_repo': 'mailu', - 'github_version': 'master', + 'github_version': os.environ.get('VERSION', 'master'), + 'versions': [ + ('1.5', '/1.5/'), + ('master', '/master/') + ], 'conf_py_path': '/docs/' } diff --git a/docs/docker-compose.yml b/docs/docker-compose.yml new file mode 100644 index 00000000..0caaa7a4 --- /dev/null +++ b/docs/docker-compose.yml @@ -0,0 +1,21 @@ +version: '3' + + +services: + docs_master: + image: mailu/docs:master + labels: + - traefik.enable=true + - traefik.port=80 + - traefik.main.frontend.rule=Host:${hostname};PathPrefix:/master/ + + docs_15: + image: mailu/docs:1.5 + labels: + - traefik.enable=true + - traefik.port=80 + - traefik.root.frontend.redirect.regex=.* + - traefik.root.frontend.redirect.replacement=/1.5/ + - traefik.root.frontend.rule=Host:${hostname};PathPrefix:/ + - traefik.main.frontend.rule=Host:${hostname};PathPrefix:/1.5/ + From 13e3862ca701f5ec5d5e2f3cbb1fff196f0220ca Mon Sep 17 00:00:00 2001 From: kaiyou Date: Tue, 16 Oct 2018 22:55:05 +0200 Subject: [PATCH 11/39] Simplify the docs configuration --- docs/_templates/layout.html | 2 -- docs/conf.py | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) delete mode 100644 docs/_templates/layout.html diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html deleted file mode 100644 index 3f424a0a..00000000 --- a/docs/_templates/layout.html +++ /dev/null @@ -1,2 +0,0 @@ -{% set version=github_version %} -{% extends "!layout.html" %} diff --git a/docs/conf.py b/docs/conf.py index e86a7b9e..4ac9de3d 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,9 +11,9 @@ master_doc = 'index' project = 'Mailu' copyright = '2018, Mailu authors' author = 'Mailu authors' -version = release = 'latest' +version = release = os.environ.get('VERSION', 'master') language = None -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'Dockerfile', 'docker-compose.yml'] pygments_style = 'sphinx' todo_include_todos = False html_theme = 'sphinx_rtd_theme' @@ -35,7 +35,7 @@ html_context = { 'display_github': True, 'github_user': 'mailu', 'github_repo': 'mailu', - 'github_version': os.environ.get('VERSION', 'master'), + 'github_version': version, 'versions': [ ('1.5', '/1.5/'), ('master', '/master/') From 1fc40bf93220e1c1b66343b1ea254d49585b59df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=C3=A4nger?= Date: Tue, 16 Oct 2018 22:57:25 +0200 Subject: [PATCH 12/39] add healthcheck for postfix --- core/postfix/Dockerfile | 3 +++ core/postfix/health.sh | 8 ++++++++ 2 files changed, 11 insertions(+) create mode 100755 core/postfix/health.sh diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index ea58ce1d..4208714a 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -7,8 +7,11 @@ RUN apk add --no-cache postfix postfix-pcre rsyslog \ COPY conf /conf COPY start.py /start.py +COPY health.sh /health.sh EXPOSE 25/tcp 10025/tcp VOLUME ["/data"] CMD /start.py + +HEALTHCHECK CMD /health.sh diff --git a/core/postfix/health.sh b/core/postfix/health.sh new file mode 100755 index 00000000..192eac25 --- /dev/null +++ b/core/postfix/health.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "$(echo QUIT|nc localhost 25|tail -n1|cut -f1 -d ' ')" = "221" ]; then + echo "ping successful" +else + echo "ping failed" + exit 1 +fi From 0bc901a722f957faab0af81a3d71aff6510cf442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=C3=A4nger?= Date: Tue, 16 Oct 2018 23:11:20 +0200 Subject: [PATCH 13/39] add healthcheck for dovecot --- core/dovecot/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index d8d4c55b..c0d3e3cd 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -13,3 +13,5 @@ EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp VOLUME ["/data", "/mail"] CMD /start.py + +HEALTHCHECK CMD echo QUIT|nc localhost 110|grep "Dovecot ready." From a412951a308c7c1e9a15d7790835f164d0e04814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20S=C3=A4nger?= Date: Tue, 16 Oct 2018 23:12:02 +0200 Subject: [PATCH 14/39] simpler healthcheck for postfix --- core/postfix/Dockerfile | 3 +-- core/postfix/health.sh | 8 -------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100755 core/postfix/health.sh diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index 4208714a..5533499e 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -7,11 +7,10 @@ RUN apk add --no-cache postfix postfix-pcre rsyslog \ COPY conf /conf COPY start.py /start.py -COPY health.sh /health.sh EXPOSE 25/tcp 10025/tcp VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD /health.sh +HEALTHCHECK CMD echo QUIT|nc localhost 25|grep "220 .* ESMTP Postfix" diff --git a/core/postfix/health.sh b/core/postfix/health.sh deleted file mode 100755 index 192eac25..00000000 --- a/core/postfix/health.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -if [ "$(echo QUIT|nc localhost 25|tail -n1|cut -f1 -d ' ')" = "221" ]; then - echo "ping successful" -else - echo "ping failed" - exit 1 -fi From 53b9c031c99ccb6c2530cacc8c54a57f92f82a58 Mon Sep 17 00:00:00 2001 From: kaiyou Date: Tue, 16 Oct 2018 23:19:48 +0200 Subject: [PATCH 15/39] Add a warning banner when not reading the stable docs --- docs/_templates/layout.html | 9 +++++++++ docs/conf.py | 1 + 2 files changed, 10 insertions(+) create mode 100644 docs/_templates/layout.html diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 00000000..63db07e2 --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,9 @@ +{% extends "!layout.html" %} +{% block document %} +{% if version != stable_version %} +
+

You are currently browsing documentation for the {{ version }} branch. Documentation for the stable {{ stable_version }} branch can be found here.

+
+{% endif %} +{{ super() }} +{% endblock %} diff --git a/docs/conf.py b/docs/conf.py index 4ac9de3d..64997eb1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -36,6 +36,7 @@ html_context = { 'github_user': 'mailu', 'github_repo': 'mailu', 'github_version': version, + 'stable_version': '1.5', 'versions': [ ('1.5', '/1.5/'), ('master', '/master/') From 4ea12deae792081d86372698dba8a4288bd68302 Mon Sep 17 00:00:00 2001 From: hacor Date: Wed, 17 Oct 2018 07:22:55 +0200 Subject: [PATCH 16/39] Added kubernetes to Mailu --- core/dovecot/Dockerfile | 4 +- core/nginx/Dockerfile | 4 +- core/nginx/conf/nginx.conf | 3 + core/postfix/Dockerfile | 2 +- core/postfix/conf/main.cf | 2 +- docs/compose/.env | 3 + docs/index.rst | 2 +- docs/kubernetes/index.rst | 26 -- docs/kubernetes/kubernetes-mailu.yaml | 419 ------------------ .../kubernetes-nginx-ingress-controller.yaml | 84 ---- docs/kubernetes/mailu/admin-ingress.yaml | 86 ++++ docs/kubernetes/mailu/admin.yaml | 63 +++ docs/kubernetes/mailu/configmap.yaml | 172 +++++++ docs/kubernetes/mailu/fetchmail.yaml | 39 ++ docs/kubernetes/mailu/front.yaml | 135 ++++++ docs/kubernetes/mailu/imap.yaml | 80 ++++ docs/kubernetes/mailu/index.rst | 193 ++++++++ docs/kubernetes/mailu/pvc.yaml | 27 ++ docs/kubernetes/mailu/rbac.yaml | 4 + docs/kubernetes/mailu/redis.yaml | 56 +++ docs/kubernetes/mailu/security-ingress.yaml | 30 ++ docs/kubernetes/mailu/security.yaml | 116 +++++ docs/kubernetes/mailu/smtp.yaml | 80 ++++ docs/kubernetes/mailu/webdav-ingress.yaml | 46 ++ docs/kubernetes/mailu/webdav.yaml | 63 +++ docs/kubernetes/mailu/webmail-ingress.yaml | 31 ++ docs/kubernetes/mailu/webmail.yaml | 59 +++ .../nginx/default-http-backend.yaml | 55 +++ docs/kubernetes/nginx/nginx-ingress.yaml | 127 ++++++ docs/kubernetes/nginx/rbac.yaml | 129 ++++++ services/rspamd/conf/worker-controller.inc | 4 + webmails/roundcube/Dockerfile | 6 +- 32 files changed, 1611 insertions(+), 539 deletions(-) delete mode 100644 docs/kubernetes/index.rst delete mode 100644 docs/kubernetes/kubernetes-mailu.yaml delete mode 100644 docs/kubernetes/kubernetes-nginx-ingress-controller.yaml create mode 100644 docs/kubernetes/mailu/admin-ingress.yaml create mode 100644 docs/kubernetes/mailu/admin.yaml create mode 100644 docs/kubernetes/mailu/configmap.yaml create mode 100644 docs/kubernetes/mailu/fetchmail.yaml create mode 100644 docs/kubernetes/mailu/front.yaml create mode 100644 docs/kubernetes/mailu/imap.yaml create mode 100644 docs/kubernetes/mailu/index.rst create mode 100644 docs/kubernetes/mailu/pvc.yaml create mode 100644 docs/kubernetes/mailu/rbac.yaml create mode 100644 docs/kubernetes/mailu/redis.yaml create mode 100644 docs/kubernetes/mailu/security-ingress.yaml create mode 100644 docs/kubernetes/mailu/security.yaml create mode 100644 docs/kubernetes/mailu/smtp.yaml create mode 100644 docs/kubernetes/mailu/webdav-ingress.yaml create mode 100644 docs/kubernetes/mailu/webdav.yaml create mode 100644 docs/kubernetes/mailu/webmail-ingress.yaml create mode 100644 docs/kubernetes/mailu/webmail.yaml create mode 100644 docs/kubernetes/nginx/default-http-backend.yaml create mode 100644 docs/kubernetes/nginx/nginx-ingress.yaml create mode 100644 docs/kubernetes/nginx/rbac.yaml diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index cacfe354..29957921 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:edge +FROM alpine:3.7 RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \ && apk add --no-cache \ @@ -11,4 +11,4 @@ COPY start.py /start.py EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp -CMD /start.py +CMD /start.py \ No newline at end of file diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 3be4b50f..49627fb7 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:edge +FROM alpine:3.7 RUN apk add --no-cache nginx nginx-mod-mail python py-jinja2 certbot openssl @@ -7,4 +7,4 @@ COPY *.py / EXPOSE 80/tcp 443/tcp 110/tcp 143/tcp 465/tcp 587/tcp 993/tcp 995/tcp 25/tcp 10025/tcp 10143/tcp -CMD /start.py +CMD /start.py \ No newline at end of file diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index 8fcda1c3..b6e0fbd3 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -34,6 +34,8 @@ http { '' $scheme; } + # Disable the main http server when on kubernetes (port 80 and 443) + {% if KUBERNETES_INGRESS != 'true' %} # Main HTTP server server { # Variables for proxifying @@ -147,6 +149,7 @@ http { proxy_set_header Content-Length ""; } } + {% endif %} # Forwarding authentication server server { diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index bb5831a2..168f3c60 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine +FROM alpine:3.7 RUN apk add --no-cache postfix postfix-sqlite postfix-pcre rsyslog python py-jinja2 diff --git a/core/postfix/conf/main.cf b/core/postfix/conf/main.cf index 2f2c6990..c1d5e4b2 100644 --- a/core/postfix/conf/main.cf +++ b/core/postfix/conf/main.cf @@ -32,7 +32,7 @@ relayhost = {{ RELAYHOST }} recipient_delimiter = {{ RECIPIENT_DELIMITER }} # Only the front server is allowed to perform xclient -smtpd_authorized_xclient_hosts={{ FRONT_ADDRESS }} +smtpd_authorized_xclient_hosts={{ RELAYNETS }} ############### # TLS diff --git a/docs/compose/.env b/docs/compose/.env index 06038bc8..e7a1f55d 100644 --- a/docs/compose/.env +++ b/docs/compose/.env @@ -55,6 +55,9 @@ WEBDAV=none # Antivirus solution (value: clamav, none) ANTIVIRUS=none +# The password for the rspamd web interface +RSPAMD_PASSWORD=Secr3tPassWord + ################################### # Mail settings ################################### diff --git a/docs/index.rst b/docs/index.rst index 0920bb96..ebfbd7a7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -55,7 +55,7 @@ the version of Mailu that you are running. configuration compose/requirements compose/setup - kubernetes/index + kubernetes/mailu/index dns reverse diff --git a/docs/kubernetes/index.rst b/docs/kubernetes/index.rst deleted file mode 100644 index efd1ab7c..00000000 --- a/docs/kubernetes/index.rst +++ /dev/null @@ -1,26 +0,0 @@ -Kubernetes setup -================ - -Please note that Kubernetes setup is not yet well supported or documented, all -tests currently run on Docker Compose. The configuration has not yet been updated -to work properly with ngin authentication proxy. - -Prepare the environment ------------------------ - -The resource configurations in this folder assume that you have `Kubernetes Ingress`_ -set up for your cluster. If you are not using the `NGINX Ingress Controller for Kubernetes`_, -please ensure that the configuration specified in the file matches your set up. - -.. _`Kubernetes Ingress`: https://kubernetes.io/docs/concepts/services-networking/ingress/ -.. _`NGINX Ingress Controller for Kubernetes`: https://github.com/kubernetes/ingress/tree/master/controllers/nginx - -Setup the Kubernetes service ----------------------------- - -Using the resource configurations is simple: - -1. ``kubectl apply -f kubernetes-nginx-ingress-controller.yaml`` to configure an ingress controller with the proper settings. (If you have one set up already you may need to port the configuration to your own ingress). -2. ``kubectl apply -f kubernetes-mailu.yaml`` to create the resources required to run Mailu. - -Based on the configuration, your Mailu instance should be available at ``mail..tld/admin`` (note that visiting just ``mail..tld`` will likely result in a 404 error). diff --git a/docs/kubernetes/kubernetes-mailu.yaml b/docs/kubernetes/kubernetes-mailu.yaml deleted file mode 100644 index a7bafccd..00000000 --- a/docs/kubernetes/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/kubernetes-nginx-ingress-controller.yaml b/docs/kubernetes/kubernetes-nginx-ingress-controller.yaml deleted file mode 100644 index 5ea9790a..00000000 --- a/docs/kubernetes/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/docs/kubernetes/mailu/admin-ingress.yaml b/docs/kubernetes/mailu/admin-ingress.yaml new file mode 100644 index 00000000..72aafa68 --- /dev/null +++ b/docs/kubernetes/mailu/admin-ingress.yaml @@ -0,0 +1,86 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: mailu-admin-ingress + namespace: mailu-mailserver + annotations: + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "0" + certmanager.k8s.io/cluster-issuer: letsencrypt-stage + ingress.kubernetes.io/permanent-redirect: "https://mail.example.com/admin/ui/" + ingress.kubernetes.io/follow-redirects: "true" + 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: admin + servicePort: 80 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: mailu-admin-ui-ingress + namespace: mailu-mailserver + annotations: + kubernetes.io/tls-acme: "true" + certmanager.k8s.io/cluster-issuer: letsencrypt-stage + ingress.kubernetes.io/rewrite-target: "/ui" + ingress.kubernetes.io/configuration-snippet: | + proxy_set_header X-Forwarded-Prefix /admin; + 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/ui" + backend: + serviceName: admin + servicePort: 80 +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: mailu-admin-static-ingress + namespace: mailu-mailserver + annotations: + kubernetes.io/tls-acme: "true" + certmanager.k8s.io/cluster-issuer: letsencrypt-stage + ingress.kubernetes.io/rewrite-target: "/static" + ingress.kubernetes.io/configuration-snippet: | + proxy_set_header X-Forwarded-Prefix /admin; + 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/static" + backend: + serviceName: admin + servicePort: 80 \ No newline at end of file diff --git a/docs/kubernetes/mailu/admin.yaml b/docs/kubernetes/mailu/admin.yaml new file mode 100644 index 00000000..435b7975 --- /dev/null +++ b/docs/kubernetes/mailu/admin.yaml @@ -0,0 +1,63 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-admin + namespace: mailu-mailserver +spec: + replicas: 1 + template: + metadata: + labels: + app: mailu-admin + role: mail + tier: backend + spec: + containers: + - name: admin + image: mailu/admin:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + volumeMounts: + - name: maildata + mountPath: /data + subPath: maildata + - name: maildata + mountPath: /dkim + subPath: dkim + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + requests: + memory: 500Mi + cpu: 500m + limits: + memory: 500Mi + cpu: 500m + volumes: + - name: maildata + persistentVolumeClaim: + claimName: mail-storage +--- + +apiVersion: v1 +kind: Service +metadata: + name: admin + namespace: mailu-mailserver + labels: + app: mailu-admin + role: mail + tier: backend +spec: + selector: + app: mailu-admin + role: mail + tier: backend + ports: + - name: http + port: 80 + protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/mailu/configmap.yaml b/docs/kubernetes/mailu/configmap.yaml new file mode 100644 index 00000000..be39fcc9 --- /dev/null +++ b/docs/kubernetes/mailu/configmap.yaml @@ -0,0 +1,172 @@ + apiVersion: v1 + kind: ConfigMap + metadata: + name: mailu-config + namespace: mailu-mailserver + data: + # Mailu main configuration file + # + # Most configuration variables can be modified through the Web interface, + # these few settings must however be configured before starting the mail + # server and require a restart upon change. + + ################################### + # Common configuration variables + ################################### + + # Set this to the path where Mailu data and configuration is stored + ROOT: "/mailu" + + # Mailu version to run (1.0, 1.1, etc. or master) + VERSION: "master" + + # Set to a randomly generated 16 bytes string + SECRET_KEY: "MySup3rS3cr3tPas" + + # Address where listening ports should bind + BIND_ADDRESS4: "127.0.0.1" + #BIND_ADDRESS6: "::1" + + # Main mail domain + DOMAIN: "example.com" + + # Hostnames for this server, separated with comas + HOSTNAMES: "mail.example.com" + + # Postmaster local part (will append the main mail domain) + POSTMASTER: "admin" + + # Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt) + TLS_FLAVOR: "cert" + + # Authentication rate limit (per source IP address) + AUTH_RATELIMIT: "100/minute;10000/hour" + + # Opt-out of statistics, replace with "True" to opt out + DISABLE_STATISTICS: "False" + + ################################### + # Kubernetes configuration + ################################### + + # Use Kubernetes Ingress Controller to handle all actions on port 80 and 443 + # This way we can make use of the advantages of the cert-manager deployment + KUBERNETES_INGRESS: "true" + POD_ADDRESS_RANGE: "10.2.0.0/16" + + ################################### + # Optional features + ################################### + + # Expose the admin interface (value: true, false) + ADMIN: "true" + # Run the admin interface in debug mode + #DEBUG: "True" + + # Choose which webmail to run if any (values: roundcube, rainloop, none) + WEBMAIL: "roundcube" + + # Dav server implementation (value: radicale, none) + WEBDAV: "radicale" + + # Antivirus solution (value: clamav, none) + ANTIVIRUS: "clamav" + + # The password for the rspamd web interface + RSPAMD_PASSWORD: "Secr3tPassWord" + + ################################### + # Mail settings + ################################### + + # Message size limit in bytes + # Default: accept messages up to 50MB + MESSAGE_SIZE_LIMIT: "50000000" + + # Networks granted relay permissions, make sure that you include your Docker + # internal network (default to 172.17.0.0/16) + # For kubernetes this is the CIDR of the pod network + RELAYNETS: "10.2.0.0/16" + + # Will relay all outgoing mails if configured + #RELAYHOST= + + # This part is needed for the XCLIENT login for postfix. This should be the POD ADDRESS range + FRONT_ADDRESS: "front.mailu-mailserver.svc.cluster.local" + + # This value is needed by the webmail to find the correct imap backend + IMAP_ADDRESS: "imap.mailu-mailserver.svc.cluster.local" + + # This value is used by Dovecot to find the Redis server in the cluster + REDIS_ADDRESS: "redis.mailu-mailserver.svc.cluster.local" + + # Fetchmail delay + FETCHMAIL_DELAY: "600" + + # Recipient delimiter, character used to delimiter localpart from custom address part + # e.g. localpart+custom@domain;tld + RECIPIENT_DELIMITER: "+" + + # DMARC rua and ruf email + DMARC_RUA: "root" + DMARC_RUF: "root" + + # Welcome email, enable and set a topic and body if you wish to send welcome + # emails to all users. + WELCOME: "false" + WELCOME_SUBJECT: "Welcome to your new email account" + WELCOME_BODY: "Welcome to your new email account, if you can read this, then it is configured properly!" + + ################################### + # Web settings + ################################### + + # Path to the admin interface if enabled + # Kubernetes addition: You need to change ALL the ingresses, when you want this URL to be different!!! + WEB_ADMIN: "/admin" + + # Path to the webmail if enabled + # Currently, this is not used, because we intended to use a different subdomain: webmail.example.com + # This option can be added in a feature release + WEB_WEBMAIL: "/webmail" + + # Website name + SITENAME: "Mailu" + + # Linked Website URL + WEBSITE: "https://example.com" + + # Registration reCaptcha settings (warning, this has some privacy impact) + # RECAPTCHA_PUBLIC_KEY= + # RECAPTCHA_PRIVATE_KEY= + + # Domain registration, uncomment to enable + # DOMAIN_REGISTRATION=true + + ################################### + # Advanced settings + ################################### + + # Docker-compose project name, this will prepended to containers names. + COMPOSE_PROJECT_NAME: "mailu" + + # Default password scheme used for newly created accounts and changed passwords + # (value: SHA512-CRYPT, SHA256-CRYPT, MD5-CRYPT, CRYPT) + PASSWORD_SCHEME: "SHA512-CRYPT" + + # Header to take the real ip from + #REAL_IP_HEADER: + + # IPs for nginx set_real_ip_from (CIDR list separated by commas) + #REAL_IP_FROM: + + # Host settings + HOST_IMAP: "imap.mailu-mailserver.svc.cluster.local" + HOST_POP3: "imap.mailu-mailserver.svc.cluster.local" + HOST_SMTP: "smtp.mailu-mailserver.svc.cluster.local" + HOST_AUTHSMTP: "smtp.mailu-mailserver.svc.cluster.local" + HOST_WEBMAIL: "webmail.mailu-mailserver.svc.cluster.local" + HOST_ADMIN: "admin.mailu-mailserver.svc.cluster.local" + HOST_WEBDAV: "webdav.mailu-mailserver.svc.cluster.local:5232" + HOST_ANTISPAM: "antispam.mailu-mailserver.svc.cluster.local:11332" + HOST_REDIS: "redis.mailu-mailserver.svc.cluster.local" diff --git a/docs/kubernetes/mailu/fetchmail.yaml b/docs/kubernetes/mailu/fetchmail.yaml new file mode 100644 index 00000000..cf3271e7 --- /dev/null +++ b/docs/kubernetes/mailu/fetchmail.yaml @@ -0,0 +1,39 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-fetchmail + namespace: mailu-mailserver +spec: + replicas: 1 + template: + metadata: + labels: + app: mailu-fetchmail + role: mail + tier: backend + spec: + containers: + - name: fetchmail + image: mailu/fetchmail:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + volumeMounts: + - name: maildata + mountPath: /data + subPath: maildata + ports: + - containerPort: 5232 + - containerPort: 80 + resources: + requests: + memory: 100Mi + cpu: 100m + limits: + memory: 100Mi + cpu: 100m + volumes: + - name: maildata + persistentVolumeClaim: + claimName: mail-storage \ No newline at end of file diff --git a/docs/kubernetes/mailu/front.yaml b/docs/kubernetes/mailu/front.yaml new file mode 100644 index 00000000..c13ecd9d --- /dev/null +++ b/docs/kubernetes/mailu/front.yaml @@ -0,0 +1,135 @@ +apiVersion: apps/v1beta2 +kind: DaemonSet +metadata: + name: mailu-front + namespace: mailu-mailserver + labels: + k8s-app: mail-loadbalancer + component: ingress-controller + type: nginx +spec: + selector: + matchLabels: + k8s-app: mail-loadbalancer + component: ingress-controller + type: nginx + template: + metadata: + labels: + k8s-app: mail-loadbalancer + component: ingress-controller + type: nginx + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/master + operator: DoesNotExist + hostNetwork: true + nodeSelector: + node-role.kubernetes.io/node: "" + dnsPolicy: ClusterFirstWithHostNet + restartPolicy: Always + terminationGracePeriodSeconds: 60 + containers: + - name: front + image: mailu/nginx:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + volumeMounts: + - name: certs + mountPath: /certs + ports: + - name: pop3 + containerPort: 110 + protocol: TCP + - name: pop3s + containerPort: 995 + protocol: TCP + - name: imap + containerPort: 143 + protocol: TCP + - name: imaps + containerPort: 993 + protocol: TCP + - name: smtp + containerPort: 25 + protocol: TCP + - name: smtp-auth + containerPort: 10025 + protocol: TCP + - name: imap-auth + containerPort: 10143 + protocol: TCP + - name: smtps + containerPort: 465 + protocol: TCP + - name: smtpd + containerPort: 587 + protocol: TCP + - name: auth + containerPort: 8000 + protocol: TCP + resources: + requests: + memory: 100Mi + cpu: 100m + limits: + memory: 200Mi + cpu: 200m + volumes: + - 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: front + namespace: mailu-mailserver + labels: + k8s-app: mail-loadbalancer + component: ingress-controller + type: nginx +spec: + selector: + k8s-app: mail-loadbalancer + component: ingress-controller + type: nginx + ports: + - name: pop3 + port: 110 + protocol: TCP + - name: pop3s + port: 995 + protocol: TCP + - name: imap + port: 143 + protocol: TCP + - name: imaps + port: 993 + protocol: TCP + - name: smtp + port: 25 + protocol: TCP + - name: smtps + port: 465 + protocol: TCP + - name: smtpd + port: 587 + protocol: TCP + - name: smtp-auth + port: 10025 + protocol: TCP + - name: imap-auth + port: 10143 + protocol: TCP diff --git a/docs/kubernetes/mailu/imap.yaml b/docs/kubernetes/mailu/imap.yaml new file mode 100644 index 00000000..37f4899e --- /dev/null +++ b/docs/kubernetes/mailu/imap.yaml @@ -0,0 +1,80 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-imap + namespace: mailu-mailserver +spec: + replicas: 1 + template: + metadata: + labels: + app: mailu-imap + role: mail + tier: backend + spec: + containers: + - name: imap + image: mailu/dovecot:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + volumeMounts: + - mountPath: /data + name: maildata + subPath: maildata + - mountPath: /mail + name: maildata + subPath: mailstate + - mountPath: /overrides + name: maildata + subPath: overrides + ports: + - containerPort: 2102 + - containerPort: 2525 + - containerPort: 143 + - containerPort: 993 + - containerPort: 4190 + resources: + requests: + memory: 1Gi + cpu: 1000m + limits: + memory: 1Gi + cpu: 1000m + volumes: + - name: maildata + persistentVolumeClaim: + claimName: mail-storage +--- +apiVersion: v1 +kind: Service +metadata: + name: imap + namespace: mailu-mailserver + 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 \ No newline at end of file diff --git a/docs/kubernetes/mailu/index.rst b/docs/kubernetes/mailu/index.rst new file mode 100644 index 00000000..ef12eb58 --- /dev/null +++ b/docs/kubernetes/mailu/index.rst @@ -0,0 +1,193 @@ +Install Mailu master on kubernetes +================================== + +Prequisites +----------- + +Structure +~~~~~~~~~ + +There’s chosen to have a double NGINX stack for Mailu, this way the main +ingress can still be used to access other websites/domains on your +cluster. This is the current structure: + +- ``NGINX Ingress controller``: Listens to the nodes ports 80 & 443. We have chosen to have a double NGINX stack for Mailu. +- ``Cert manager``: Creates automatic Lets Encrypt certificates based on an ``Ingress``-objects domain name. +- ``Mailu NGINX Front daemonset``: This daemonset runs in parallel with the Nginx Ingress Controller and only listens on all E-mail specific ports (25, 110, 143, 587,...) +- ``Mailu components``: All Mailu components (imap, smtp, security, webmail,...) are split into separate files to make them more handy to use, you can find the ``YAML`` files in this directory + +What you need +~~~~~~~~~~~~~ + +- A working Kubernetes cluster (tested with 1.10.5) +- A working `cert-manager`_ installation +- A working nginx-ingress controller needed for the lets-encrypt + certificates. You can find those files in the ``nginx`` subfolder + +Cert manager +^^^^^^^^^^^^ + +The ``Cert-manager`` is quite easy to deploy using Helm when reading the +`docs`_. After booting the ``Cert-manager`` you’ll need a +``ClusterIssuer`` which takes care of all required certificates through +``Ingress`` items. We chose to provide a ``clusterIssuer`` so you can provide SSL certificates +for other namespaces (different websites/services), if you don't need this option, you can easily change this by +changing ``clusterIssuer`` to ``Issuer`` and adding the ``namespace: mailu-mailserver`` to the metadata. +An example of a production and a staging ``clusterIssuer``: + +.. code:: yaml + + # This clusterIssuer example uses the staging environment for testing first + apiVersion: certmanager.k8s.io/v1alpha1 + kind: ClusterIssuer + metadata: + name: letsencrypt-stage + spec: + acme: + email: something@example.com + http01: {} + privateKeySecretRef: + name: letsencrypt-stage + server: https://acme-staging-v02.api.letsencrypt.org/directory + +.. code:: yaml + + # This clusterIssuer example uses the production environment + apiVersion: certmanager.k8s.io/v1alpha1 + kind: ClusterIssuer + metadata: + name: letsencrypt-prod + spec: + acme: + email: something@example.com + http01: {} + privateKeySecretRef: + name: letsencrypt-prod + server: https://acme-v02.api.letsencrypt.org/directory + +**IMPORTANT**: All ``*-ingress.yaml`` files use the ``letsencrypt-stage`` ``clusterIssuer``. If you are ready for production, +change this field in all ``*-ingress.yaml`` files to ``letsencrypt-prod`` or whatever name you chose for the production. +If you choose for ``Issuer`` instead of ``clusterIssuer`` you also need to change the annotation to ``certmanager.k8s.io/issuer`` instead of ``certmanager.k8s.io/cluster-issuer`` + +Deploying Mailu +--------------- + +All manifests can be found in the ``mailu`` subdirectory. All commands +below need to be run from this subdirectory + +Personalization +~~~~~~~~~~~~~~~ + +- All services run in the same namespace, currently ``mailu-mailserver``. So if you want to use a different one, change the ``namespace`` value in **every** file +- Check the ``storage-class`` field in the ``pvc.yaml`` file, you can also change the sizes to your liking. Note that you need ``RWX`` (read-write-many) and ``RWO`` (read-write-once) storageclasses. +- Check the ``configmap.yaml`` and adapt it to your needs. Be sure to check the kubernetes DNS values at the end (if you use a different namespace) +- Check the ``*-ingress.yaml`` files and change it to the domain you want (this is for the kubernetes ingress controller to handle the admin, webmail, webdav and auth connections) + +Installation +------------ + +Boot the Mailu components +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To start Mailu, run the following commands from the ``docs/kubernetes/mailu`` directory + +.. code-block:: bash + + kubectl create -f rbac.yaml + kubectl create -f configmap.yaml + kubectl create -f pvc.yaml + kubectl create -f redis.yaml + kubectl create -f front.yaml + kubectl create -f webmail.yaml + kubectl create -f imap.yaml + kubectl create -f security.yaml + kubectl create -f smtp.yaml + kubectl create -f fetchmail.yaml + kubectl create -f admin.yaml + kubectl create -f webdav.yaml + kubectl create -f admin-ingress.yaml + kubectl create -f webdav-ingress.yaml + kubectl create -f security-ingress.yaml + kubectl create -f webmail-ingress.yaml + + +Create the first admin account +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When the cluster is online you need to create you master user to access https://mail.example.com/admin +Enter the main ``admin`` pod to create the root account: + +.. code-block:: bash + + kubectl -n mailu-mailserver get po + kubectl -n mailu-mailserver exec -it mailu-admin-.... /bin/sh + +And in the pod run the following command. The command uses following entries: + +.. code-block:: bash + + python manage.py admin root example.com password + +- ``admin`` Make it an admin user +- ``root`` The first part of the e-mail adres (ROOT@example.com) +- ``example.com`` the domain appendix +- ``password`` the chosen password for the user + + +Now you should be able to login on the mail account: https://mail.example.com/admin + +Adaptations +----------- + +Dovecot +~~~~~~~ + +- If you are using Dovecot on a shared file system (Glusterfs, NFS,...), you need to create a special override otherwise a lot of indexing errors will occur on your Dovecot pod. +- I also higher the number of max connections per IP. Now it's limited to 10. + +Enter the dovecot pod: + +.. code:: bash + + kubectl -n mailu-mailserver get po + kubectl -n mailu-mailserver exec -it mailu-imap-.... /bin/sh + +Create the file ``overrides/dovecot.conf`` + +.. code:: bash + + vi /overrides/dovecot.conf + +And enter following contents: + +.. code:: bash + + mail_nfs_index = yes + mail_nfs_storage = yes + mail_fsync = always + mmap_disable = yes + mail_max_userip_connections=100 + +Save and close the file and delete the imap pod to get it recreated. + +.. code:: bash + + kubectl -n mailu-mailserver delete po/mailu-imap-.... + +Wait for the pod to recreate and you're online! +Happy mailing! + +.. _here: https://github.com/hacor/Mailu/blob/master/core/postfix/conf/main.cf#L35 +.. _cert-manager: https://github.com/jetstack/cert-manager +.. _docs: https://cert-manager.readthedocs.io/en/latest/getting-started/2-installing.html + +Imap login fix +~~~~~~~~~~~~~~ + +If it seems you're not able to login using IMAP on your Mailu accounts, check the logs of the imap container to see whether it's a permissions problem on the database. +This problem can be easily fixed by running following commands: + +.. code:: bash + + kubectl -n mailu-mailserver exec -it maolu-imap-... /bin/sh + chmod 777 /data/main.db diff --git a/docs/kubernetes/mailu/pvc.yaml b/docs/kubernetes/mailu/pvc.yaml new file mode 100644 index 00000000..0ec2852f --- /dev/null +++ b/docs/kubernetes/mailu/pvc.yaml @@ -0,0 +1,27 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: redis-hdd + namespace: mailu-mailserver + annotations: + volume.beta.kubernetes.io/storage-class: "glusterblock-hdd" +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: mail-storage + namespace: mailu-mailserver + annotations: + volume.beta.kubernetes.io/storage-class: "gluster-heketi-hdd" +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 100Gi diff --git a/docs/kubernetes/mailu/rbac.yaml b/docs/kubernetes/mailu/rbac.yaml new file mode 100644 index 00000000..33255130 --- /dev/null +++ b/docs/kubernetes/mailu/rbac.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: mailu-mailserver \ No newline at end of file diff --git a/docs/kubernetes/mailu/redis.yaml b/docs/kubernetes/mailu/redis.yaml new file mode 100644 index 00000000..d6bb1eb8 --- /dev/null +++ b/docs/kubernetes/mailu/redis.yaml @@ -0,0 +1,56 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-redis + namespace: mailu-mailserver +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 + resources: + requests: + memory: 200Mi + cpu: 100m + limits: + memory: 300Mi + cpu: 200m + volumes: + - name: redisdata + persistentVolumeClaim: + claimName: redis-hdd +--- + +apiVersion: v1 +kind: Service +metadata: + name: redis + namespace: mailu-mailserver + labels: + app: mailu-redis + role: mail + tier: backend +spec: + selector: + app: mailu-redis + role: mail + tier: backend + ports: + - name: redis + port: 6379 + protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/mailu/security-ingress.yaml b/docs/kubernetes/mailu/security-ingress.yaml new file mode 100644 index 00000000..74ced47e --- /dev/null +++ b/docs/kubernetes/mailu/security-ingress.yaml @@ -0,0 +1,30 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: mailu-antispam-ingress + namespace: mailu-mailserver + annotations: + kubernetes.io/tls-acme: "true" + certmanager.k8s.io/cluster-issuer: letsencrypt-stage + ingress.kubernetes.io/configuration-snippet: | + rewrite ^/admin/antispam/(.*) /$1 break; + auth_request /internal/auth/admin; + proxy_set_header X-Real-IP ""; + proxy_set_header X-Forwarded-For ""; + labels: + app: mailu + role: mail + tier: frontend +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/antispam" + backend: + serviceName: antispam + servicePort: 11334 \ No newline at end of file diff --git a/docs/kubernetes/mailu/security.yaml b/docs/kubernetes/mailu/security.yaml new file mode 100644 index 00000000..80fde812 --- /dev/null +++ b/docs/kubernetes/mailu/security.yaml @@ -0,0 +1,116 @@ + +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-security + namespace: mailu-mailserver +spec: + replicas: 1 + template: + metadata: + labels: + app: mailu-security + role: mail + tier: backend + spec: + containers: + - name: antispam + image: mailu/rspamd:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + resources: + requests: + memory: 100Mi + cpu: 100m + limits: + memory: 200Mi + cpu: 200m + ports: + - name: antispam + containerPort: 11332 + protocol: TCP + - name: antispam-http + containerPort: 11334 + protocol: TCP + volumeMounts: + - name: filter + subPath: filter + mountPath: /var/lib/rspamd + - name: filter + mountPath: /dkim + subPath: dkim + - name: filter + mountPath: /etc/rspamd/override.d + subPath: rspamd-overrides + - name: antivirus + image: mailu/clamav:master + imagePullPolicy: Always + resources: + requests: + memory: 1Gi + cpu: 1000m + limits: + memory: 2Gi + cpu: 1000m + envFrom: + - configMapRef: + name: mailu-config + ports: + - name: antivirus + containerPort: 3310 + protocol: TCP + volumeMounts: + - name: filter + subPath: filter + mountPath: /data + volumes: + - name: filter + persistentVolumeClaim: + claimName: mail-storage + +--- + +apiVersion: v1 +kind: Service +metadata: + name: antispam + namespace: mailu-mailserver + labels: + app: mailu-antispam + role: mail + tier: backend +spec: + selector: + app: mailu-security + role: mail + tier: backend + ports: + - name: antispam + port: 11332 + protocol: TCP + - name: antispam-http + protocol: TCP + port: 11334 + +--- + +apiVersion: v1 +kind: Service +metadata: + name: antivirus + namespace: mailu-mailserver + labels: + app: mailu-antivirus + role: mail + tier: backend +spec: + selector: + app: mailu-security + role: mail + tier: backend + ports: + - name: antivirus + port: 3310 + protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/mailu/smtp.yaml b/docs/kubernetes/mailu/smtp.yaml new file mode 100644 index 00000000..926a2b7c --- /dev/null +++ b/docs/kubernetes/mailu/smtp.yaml @@ -0,0 +1,80 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-smtp + namespace: mailu-mailserver +spec: + replicas: 1 + template: + metadata: + labels: + app: mailu-smtp + role: mail + tier: backend + spec: + containers: + - name: smtp + image: mailu/postfix:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + resources: + requests: + memory: 2Gi + cpu: 500m + limits: + memory: 2Gi + cpu: 500m + volumeMounts: + - mountPath: /data + name: maildata + subPath: maildata + - mountPath: /overrides + name: maildata + subPath: overrides + ports: + - name: smtp + containerPort: 25 + protocol: TCP + - name: smtp-ssl + containerPort: 465 + protocol: TCP + - name: smtp-starttls + containerPort: 587 + protocol: TCP + - name: smtp-auth + containerPort: 10025 + protocol: TCP + volumes: + - name: maildata + persistentVolumeClaim: + claimName: mail-storage +--- +apiVersion: v1 +kind: Service +metadata: + name: smtp + namespace: mailu-mailserver + 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 + - name: smtp-auth + port: 10025 + protocol: TCP diff --git a/docs/kubernetes/mailu/webdav-ingress.yaml b/docs/kubernetes/mailu/webdav-ingress.yaml new file mode 100644 index 00000000..3498eb02 --- /dev/null +++ b/docs/kubernetes/mailu/webdav-ingress.yaml @@ -0,0 +1,46 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: mailu-webdav-ingress + namespace: mailu-mailserver + annotations: + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "0" + certmanager.k8s.io/cluster-issuer: letsencrypt-stage + #ingress.kubernetes.io/auth-url: http://admin.mailu-mailserver.svc.cluster.local/internal/auth/basic + ingress.kubernetes.io/configuration-snippet: | + rewrite ^/webdav/(.*) /$1 break; + auth_request /internal/auth/basic; + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + auth_request_set $user $upstream_http_x_user; + proxy_set_header X-Remote-User $user; + proxy_set_header X-Script-Name /webdav; + ingress.kubernetes.io/server-snippet: | + location /internal { + internal; + + proxy_set_header Authorization $http_authorization; + proxy_pass_header Authorization; + proxy_pass http://admin.mailu-mailserver.svc.cluster.local; + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + } + labels: + app: mailu + role: mail + tier: frontend +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: "/webdav" + backend: + serviceName: webdav + servicePort: 5232 \ No newline at end of file diff --git a/docs/kubernetes/mailu/webdav.yaml b/docs/kubernetes/mailu/webdav.yaml new file mode 100644 index 00000000..07b7733c --- /dev/null +++ b/docs/kubernetes/mailu/webdav.yaml @@ -0,0 +1,63 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-webdav + namespace: mailu-mailserver +spec: + replicas: 1 + template: + metadata: + labels: + app: mailu-webdav + role: mail + tier: backend + spec: + containers: + - name: radicale + image: mailu/radicale:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + volumeMounts: + - mountPath: /data + name: maildata + subPath: dav + ports: + - containerPort: 5232 + - containerPort: 80 + resources: + requests: + memory: 100Mi + cpu: 100m + limits: + memory: 100Mi + cpu: 100m + volumes: + - name: maildata + persistentVolumeClaim: + claimName: mail-storage +--- + +apiVersion: v1 +kind: Service +metadata: + name: webdav + namespace: mailu-mailserver + labels: + app: mailu-webdav + role: mail + tier: backend +spec: + selector: + app: mailu-webdav + role: mail + tier: backend + ports: + ports: + - name: http + port: 80 + protocol: TCP + - name: http-ui + port: 5232 + protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/mailu/webmail-ingress.yaml b/docs/kubernetes/mailu/webmail-ingress.yaml new file mode 100644 index 00000000..40655ca2 --- /dev/null +++ b/docs/kubernetes/mailu/webmail-ingress.yaml @@ -0,0 +1,31 @@ +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: mailu-webmail-ingress + namespace: mailu-mailserver + annotations: + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "0" + certmanager.k8s.io/cluster-issuer: letsencrypt-stage + nginx.ingress.kubernetes.io/configuration-snippet: | + proxy_set_header Host $http_host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto; + labels: + app: mailu + role: mail + tier: backend +spec: + tls: + - hosts: + - "webmail.example.com" + secretName: letsencrypt-webmail # If unsure how to generate these, check out https://github.com/ployst/docker-letsencrypt + rules: + - host: "webmail.example.com" + http: + paths: + - path: "/" + backend: + serviceName: webmail + servicePort: 80 \ No newline at end of file diff --git a/docs/kubernetes/mailu/webmail.yaml b/docs/kubernetes/mailu/webmail.yaml new file mode 100644 index 00000000..bbbeb09d --- /dev/null +++ b/docs/kubernetes/mailu/webmail.yaml @@ -0,0 +1,59 @@ + +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: mailu-roundcube + namespace: mailu-mailserver +spec: + replicas: 1 + template: + metadata: + labels: + app: mailu-roundcube + role: mail + tier: frontend + spec: + containers: + - name: roundcube + image: mailu/roundcube:master + imagePullPolicy: Always + envFrom: + - configMapRef: + name: mailu-config + resources: + requests: + memory: 100Mi + cpu: 100m + limits: + memory: 200Mi + cpu: 200m + volumeMounts: + - mountPath: /data + name: maildata + subPath: webmail + ports: + - containerPort: 80 + volumes: + - name: maildata + persistentVolumeClaim: + claimName: mail-storage +--- +apiVersion: v1 +kind: Service +metadata: + name: webmail + namespace: mailu-mailserver + labels: + app: mailu-roundcube + role: mail + tier: frontend +spec: + selector: + app: mailu-roundcube + role: mail + tier: frontend + ports: + ports: + - name: http + port: 80 + protocol: TCP diff --git a/docs/kubernetes/nginx/default-http-backend.yaml b/docs/kubernetes/nginx/default-http-backend.yaml new file mode 100644 index 00000000..097fe7c5 --- /dev/null +++ b/docs/kubernetes/nginx/default-http-backend.yaml @@ -0,0 +1,55 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: default-http-backend + labels: + app: default-http-backend + namespace: kube-ingress +spec: + replicas: 1 + selector: + matchLabels: + app: default-http-backend + template: + metadata: + labels: + app: default-http-backend + spec: + terminationGracePeriodSeconds: 60 + containers: + - name: default-http-backend + # Any image is permissible as long as: + # 1. It serves a 404 page at / + # 2. It serves 200 on a /healthz endpoint + image: gcr.io/google_containers/defaultbackend:1.4 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + scheme: HTTP + initialDelaySeconds: 30 + timeoutSeconds: 5 + ports: + - containerPort: 8080 + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi +--- + +apiVersion: v1 +kind: Service +metadata: + name: default-http-backend + namespace: kube-ingress + labels: + app: default-http-backend +spec: + ports: + - port: 80 + targetPort: 8080 + selector: + app: default-http-backend \ No newline at end of file diff --git a/docs/kubernetes/nginx/nginx-ingress.yaml b/docs/kubernetes/nginx/nginx-ingress.yaml new file mode 100644 index 00000000..d8b71e21 --- /dev/null +++ b/docs/kubernetes/nginx/nginx-ingress.yaml @@ -0,0 +1,127 @@ +apiVersion: v1 +kind: Service +metadata: + # keep it under 24 chars + name: ingress-lb + namespace: kube-ingress + labels: + k8s-app: ingress-lb + component: ingress-controller +spec: + type: ClusterIP + selector: + k8s-app: ingress-lb + component: ingress-controller + ports: + - name: http + protocol: TCP + port: 80 + targetPort: 80 + - name: https + protocol: TCP + port: 443 + targetPort: 443 +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: udp-services + namespace: kube-ingress + +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: tcp-services + namespace: kube-ingress +data: + +--- +apiVersion: v1 +data: + enable-vts-status: "true" +kind: ConfigMap +metadata: + name: nginx-ingress-lb-conf + namespace: kube-ingress +--- +apiVersion: apps/v1beta2 +kind: DaemonSet +metadata: + name: ingress-controller + namespace: kube-ingress + annotations: + prometheus.io/port: "10254" + prometheus.io/scrape: "true" + labels: + k8s-app: ingress-lb + component: ingress-controller + type: nginx +spec: + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + type: RollingUpdate + selector: + matchLabels: + k8s-app: ingress-lb + component: ingress-controller + type: nginx + template: + metadata: + labels: + k8s-app: ingress-lb + component: ingress-controller + type: nginx + spec: + serviceAccount: kube-nginx-ingress + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/master + operator: DoesNotExist + containers: + - name: nginx-ingress-lb + image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.16.2 + args: + - /nginx-ingress-controller + - --default-backend-service=$(POD_NAMESPACE)/default-http-backend + - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services + - --udp-services-configmap=$(POD_NAMESPACE)/udp-services + - --annotations-prefix=ingress.kubernetes.io + - --enable-ssl-passthrough + # use downward API + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + ports: + - name: http + containerPort: 80 + - name: https + containerPort: 443 + readinessProbe: + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + livenessProbe: + initialDelaySeconds: 10 + timeoutSeconds: 1 + httpGet: + path: /healthz + port: 10254 + scheme: HTTP + hostNetwork: true + nodeSelector: + node-role.kubernetes.io/node: "" + dnsPolicy: ClusterFirstWithHostNet + restartPolicy: Always + terminationGracePeriodSeconds: 60 diff --git a/docs/kubernetes/nginx/rbac.yaml b/docs/kubernetes/nginx/rbac.yaml new file mode 100644 index 00000000..d3c01384 --- /dev/null +++ b/docs/kubernetes/nginx/rbac.yaml @@ -0,0 +1,129 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: kube-ingress +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kube-nginx-ingress + namespace: kube-ingress +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: kube-nginx-ingress +rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - nodes + - pods + - secrets + verbs: + - list + - watch + - update + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "extensions" + resources: + - ingresses/status + verbs: + - update +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: kube-nginx-ingress + namespace: kube-ingress +rules: + - apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - namespaces + verbs: + - get + - apiGroups: + - "" + resources: + - configmaps + resourceNames: + - "ingress-controller-leader-nginx" + verbs: + - get + - update + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - apiGroups: + - "" + resources: + - endpoints + verbs: + - get + - create + - update +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: kube-nginx-ingress + namespace: kube-ingress +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: kube-nginx-ingress +subjects: + - kind: ServiceAccount + name: kube-nginx-ingress + namespace: kube-ingress +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: kube-nginx-ingress +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kube-nginx-ingress +subjects: + - kind: ServiceAccount + name: kube-nginx-ingress + namespace: kube-ingress \ No newline at end of file diff --git a/services/rspamd/conf/worker-controller.inc b/services/rspamd/conf/worker-controller.inc index 6a020672..d3ab55f4 100644 --- a/services/rspamd/conf/worker-controller.inc +++ b/services/rspamd/conf/worker-controller.inc @@ -1,3 +1,7 @@ bind_socket = "*:11334"; +{% if RSPAMD_PASSWORD %} +password = "{{ RSPAMD_PASSWORD }}"; +{% else %} password = "mailu"; +{% endif %} secure_ip = "{{ FRONT_ADDRESS }}"; diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index c779e71a..e8a1aeaf 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -4,10 +4,10 @@ RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ - libpng12-dev \ + libpng-dev \ && docker-php-ext-install pdo_mysql mcrypt zip -ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.3.6/roundcubemail-1.3.6-complete.tar.gz +ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.3.7/roundcubemail-1.3.7-complete.tar.gz RUN echo date.timezone=UTC > /usr/local/etc/php/conf.d/timezone.ini @@ -28,4 +28,4 @@ COPY config.inc.php /var/www/html/config/ COPY start.sh /start.sh -CMD ["/start.sh"] +CMD ["/start.sh"] \ No newline at end of file From e67a0d464b16fb339710e61b90c91798db7e30d8 Mon Sep 17 00:00:00 2001 From: Hans Cornelis Date: Wed, 17 Oct 2018 07:44:21 +0200 Subject: [PATCH 17/39] Deleted old folder --- core/dovecot/Dockerfile_BACKUP_7007 | 19 +++ core/dovecot/Dockerfile_BASE_7007 | 14 ++ core/dovecot/Dockerfile_LOCAL_7007 | 14 ++ core/dovecot/Dockerfile_REMOTE_7007 | 15 ++ docs/kubernetes/1.6/README.md | 157 ------------------ docs/kubernetes/1.6/mailu/admin.yaml | 64 ------- docs/kubernetes/1.6/mailu/configmap.yaml | 153 ----------------- docs/kubernetes/1.6/mailu/fetchmail.yaml | 39 ----- docs/kubernetes/1.6/mailu/front.yaml | 129 -------------- docs/kubernetes/1.6/mailu/imap.yaml | 80 --------- docs/kubernetes/1.6/mailu/ingress-ssl.yaml | 32 ---- docs/kubernetes/1.6/mailu/pvc.yaml | 27 --- docs/kubernetes/1.6/mailu/rbac.yaml | 4 - docs/kubernetes/1.6/mailu/redis.yaml | 56 ------- docs/kubernetes/1.6/mailu/security.yaml | 110 ------------ docs/kubernetes/1.6/mailu/smtp.yaml | 80 --------- docs/kubernetes/1.6/mailu/static-ips.yaml | 0 docs/kubernetes/1.6/mailu/webdav.yaml | 63 ------- docs/kubernetes/1.6/mailu/webmail.yaml | 59 ------- .../1.6/nginx/default-http-backend.yaml | 55 ------ docs/kubernetes/1.6/nginx/nginx-ingress.yaml | 139 ---------------- docs/kubernetes/1.6/nginx/rbac.yaml | 129 -------------- 22 files changed, 62 insertions(+), 1376 deletions(-) create mode 100644 core/dovecot/Dockerfile_BACKUP_7007 create mode 100644 core/dovecot/Dockerfile_BASE_7007 create mode 100644 core/dovecot/Dockerfile_LOCAL_7007 create mode 100644 core/dovecot/Dockerfile_REMOTE_7007 delete mode 100644 docs/kubernetes/1.6/README.md delete mode 100644 docs/kubernetes/1.6/mailu/admin.yaml delete mode 100644 docs/kubernetes/1.6/mailu/configmap.yaml delete mode 100644 docs/kubernetes/1.6/mailu/fetchmail.yaml delete mode 100644 docs/kubernetes/1.6/mailu/front.yaml delete mode 100644 docs/kubernetes/1.6/mailu/imap.yaml delete mode 100644 docs/kubernetes/1.6/mailu/ingress-ssl.yaml delete mode 100644 docs/kubernetes/1.6/mailu/pvc.yaml delete mode 100644 docs/kubernetes/1.6/mailu/rbac.yaml delete mode 100644 docs/kubernetes/1.6/mailu/redis.yaml delete mode 100644 docs/kubernetes/1.6/mailu/security.yaml delete mode 100644 docs/kubernetes/1.6/mailu/smtp.yaml delete mode 100644 docs/kubernetes/1.6/mailu/static-ips.yaml delete mode 100644 docs/kubernetes/1.6/mailu/webdav.yaml delete mode 100644 docs/kubernetes/1.6/mailu/webmail.yaml delete mode 100644 docs/kubernetes/1.6/nginx/default-http-backend.yaml delete mode 100644 docs/kubernetes/1.6/nginx/nginx-ingress.yaml delete mode 100644 docs/kubernetes/1.6/nginx/rbac.yaml diff --git a/core/dovecot/Dockerfile_BACKUP_7007 b/core/dovecot/Dockerfile_BACKUP_7007 new file mode 100644 index 00000000..b5590a73 --- /dev/null +++ b/core/dovecot/Dockerfile_BACKUP_7007 @@ -0,0 +1,19 @@ +<<<<<<< HEAD +FROM alpine:3.7 +======= +FROM alpine:3.8 +>>>>>>> upstream/master + +RUN apk add --no-cache \ + dovecot dovecot-pigeonhole-plugin dovecot-fts-lucene rspamd-client \ + python3 py3-pip \ + && pip3 install --upgrade pip \ + && pip3 install jinja2 podop tenacity + +COPY conf /conf +COPY start.py /start.py + +EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp +VOLUME ["/data", "/mail"] + +CMD /start.py \ No newline at end of file diff --git a/core/dovecot/Dockerfile_BASE_7007 b/core/dovecot/Dockerfile_BASE_7007 new file mode 100644 index 00000000..cacfe354 --- /dev/null +++ b/core/dovecot/Dockerfile_BASE_7007 @@ -0,0 +1,14 @@ +FROM alpine:edge + +RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \ + && apk add --no-cache \ + dovecot dovecot-sqlite dovecot-pigeonhole-plugin dovecot-pigeonhole-plugin-extdata \ + rspamd-client@testing python py-jinja2 + +COPY conf /conf +COPY sieve /var/lib/dovecot +COPY start.py /start.py + +EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp + +CMD /start.py diff --git a/core/dovecot/Dockerfile_LOCAL_7007 b/core/dovecot/Dockerfile_LOCAL_7007 new file mode 100644 index 00000000..29957921 --- /dev/null +++ b/core/dovecot/Dockerfile_LOCAL_7007 @@ -0,0 +1,14 @@ +FROM alpine:3.7 + +RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \ + && apk add --no-cache \ + dovecot dovecot-sqlite dovecot-pigeonhole-plugin dovecot-pigeonhole-plugin-extdata \ + rspamd-client@testing python py-jinja2 + +COPY conf /conf +COPY sieve /var/lib/dovecot +COPY start.py /start.py + +EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp + +CMD /start.py \ No newline at end of file diff --git a/core/dovecot/Dockerfile_REMOTE_7007 b/core/dovecot/Dockerfile_REMOTE_7007 new file mode 100644 index 00000000..d8d4c55b --- /dev/null +++ b/core/dovecot/Dockerfile_REMOTE_7007 @@ -0,0 +1,15 @@ +FROM alpine:3.8 + +RUN apk add --no-cache \ + dovecot dovecot-pigeonhole-plugin dovecot-fts-lucene rspamd-client \ + python3 py3-pip \ + && pip3 install --upgrade pip \ + && pip3 install jinja2 podop tenacity + +COPY conf /conf +COPY start.py /start.py + +EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp +VOLUME ["/data", "/mail"] + +CMD /start.py diff --git a/docs/kubernetes/1.6/README.md b/docs/kubernetes/1.6/README.md deleted file mode 100644 index c0dd935b..00000000 --- a/docs/kubernetes/1.6/README.md +++ /dev/null @@ -1,157 +0,0 @@ -# Install Mailu master on kubernetes - -## Prequisites - -### Structure - -There's chosen to have a double NGINX stack for Mailu, this way the main ingress can still be used to access other websites/domains on your cluster. This is the current structure: - -- `NGINX Ingress controller`: Listens to the nodes ports 80 & 443 and directly forwards all TCP traffic on the E-amail ports (993,143,25,587,...). This is because this `DaemonSet` already consumes ports 80 & 443 and uses `hostNetwork: true` -- `Cert manager`: Creates automatic Lets Encrypt certificates based on an `Ingress`-objects domain name. -- `Mailu NGINX Front container`: This container receives all the mail traffic forwarded from the ingress controller. The web traffic is also forwarded based on an ingress -- `Mailu components`: All Mailu components are split into separate files to make them more - -### What you need -- A working Kubernetes cluster (tested with 1.10.5) -- A working [cert-manager](https://github.com/jetstack/cert-manager) installation -- A working nginx-ingress controller needed for the lets-encrypt certificates. You can find those files in the `nginx` subfolder - -#### Cert manager - -The `Cert-manager` is quite easy to deploy using Helm when reading the [docs](https://cert-manager.readthedocs.io/en/latest/getting-started/2-installing.html). -After booting the `Cert-manager` you'll need a `ClusterIssuer` which takes care of all required certificates through `Ingress` items. An example: - -```yaml -apiVersion: certmanager.k8s.io/v1alpha1 -kind: ClusterIssuer -metadata: - name: letsencrypt-prod -spec: - acme: - email: something@example.com - http01: {} - privateKeySecretRef: - key: "" - name: letsencrypt-stage - server: https://acme-v02.api.letsencrypt.org/directory -``` - -## Deploying Mailu - -All manifests can be found in the `mailu` subdirectory. All commands below need to be run from this subdirectory - -### Personalization -- All services run in the same namespace, currently `mailu-mailserver`. So if you want to use a different one, change the `namespace` value in **every** file -- Check the `storage-class` field in the `pvc.yaml` file, you can also change the sizes to your liking. Note that you need `RWX` (read-write-many) and `RWO` (read-write-once) storageclasses. -- Check the `configmap.yaml` and adapt it to your needs. Be sure to check the kubernetes DNS values at the end (if you use a different namespace) -- Check the `ingress-ssl.yaml` and change it to the domain you want (this is for the kubernetes ingress controller, it will forward to `mailu/nginx` a.k.a. the `front` pod) - -## Installation -First run the command to start Mailu: - -```bash -kubectl create -f rbac.yaml -kubectl create -f configmap.yaml -kubectl create -f pvc.yaml -kubectl create -f ingress-ssl.yaml -kubectl create -f redis.yaml -kubectl create -f front.yaml -kubectl create -f webmail.yaml -kubectl create -f imap.yaml -kubectl create -f security.yaml -kubectl create -f smtp.yaml -kubectl create -f fetchmail.yaml -kubectl create -f admin.yaml -kubectl create -f webdav.yaml -``` - -## Create the first admin account - -When the cluster is online you need to create you master user to access `https://mail.example.com/admin`. -Enter the main `admin` pod to create the root account: - -```bash -kubectl -n mailu-mailserver get po -kubectl -n mailu-mailserver exec -it mailu-admin-.... /bin/sh -``` - -And in the pod run the following command. The command uses following entries: -- `admin` Make it an admin user -- `root` The first part of the e-mail adres (ROOT@example.com) -- `example.com` the domain appendix -- `password` the chosen password for the user - -```bash -python manage.py admin root example.com password -``` - -Now you should be able to login on the mail account: `https://mail.example.com/admin` - -## Adaptations - -### Postfix -I noticed you need an override for the `postfix` server in order to be able to send mail. I noticed Google wasn't able to deliver mail to my account and it had to do with the `smtpd_authorized_xclient_hosts` value in the config file. The config can be read [here](https://github.com/hacor/Mailu/blob/master/core/postfix/conf/main.cf#L35) and is pointing to a single IP of the service. But the requests come from the host IPs (the NGINX Ingress proxy) and they don't use the service specific IP. - -Enter the `postfix` pod: - -```bash -kubectl -n mailu-mailserver get po -kubectl -n mailu-mailserver exec -it mailu-smtp-.... /bin/sh -``` - -Now you're in the pod, create an override file like so: - -```bash -vi /overrides/postfix.cf -``` - -And give it the following contents, off course replacing `10.2.0.0/16` with the CIDR of your pod range. This way the NGINX pods can also restart and your mail server will still operate - -```bash -not_needed = true -smtpd_authorized_xclient_hosts = 10.2.0.0/16 -``` - -The first line seems stupid, but is needed because its pasted after a #, so from the second line we're really in action. -Save and close the file and exit. Now you need to delete the pod in order to recreate the config file. - -```bash -kubectl -n mailu-mailserver delete po/mailu-smtp-.... -``` - -### Dovecot -- If you are using Dovecot on a shared file system (Glusterfs, NFS,...), you need to create a special override otherwise a lot of indexing errors will occur on your Dovecot pod. -- I also higher the number of max connections per IP. Now it's limited to 10. -Enter the dovecot pod: - -```bash -kubectl -n mailu-mailserver get po -kubectl -n mailu-mailserver exec -it mailu-imap-.... /bin/sh -``` - -Create the file `/overrides/dovecot.conf` - -```bash -vi /overrides/dovecot.conf -``` - -And enter following contents: -```bash -mail_nfs_index = yes -mail_nfs_storage = yes -mail_fsync = always -mmap_disable = yes -mail_max_userip_connections=100 -``` - -Save and close the file and delete the imap pod to get it recreated. - -```bash -kubectl -n mailu-mailserver delete po/mailu-imap-.... -``` - -Wait for the pod to recreate and you're online! -Happy mailing! - -Wait for the pod to recreate and you're online! -Happy mailing! \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/admin.yaml b/docs/kubernetes/1.6/mailu/admin.yaml deleted file mode 100644 index b36760a2..00000000 --- a/docs/kubernetes/1.6/mailu/admin.yaml +++ /dev/null @@ -1,64 +0,0 @@ - -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-admin - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-admin - role: mail - tier: backend - spec: - containers: - - name: admin - image: mailu/admin:master - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - volumeMounts: - - name: maildata - mountPath: /data - subPath: maildata - - name: maildata - mountPath: /dkim - subPath: dkim - ports: - - name: http - containerPort: 80 - protocol: TCP - resources: - requests: - memory: 500Mi - cpu: 500m - limits: - memory: 500Mi - cpu: 500m - volumes: - - name: maildata - persistentVolumeClaim: - claimName: mail-storage ---- - -apiVersion: v1 -kind: Service -metadata: - name: admin - namespace: mailu-mailserver - labels: - app: mailu-admin - role: mail - tier: backend -spec: - selector: - app: mailu-admin - role: mail - tier: backend - ports: - - name: http - port: 80 - protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/configmap.yaml b/docs/kubernetes/1.6/mailu/configmap.yaml deleted file mode 100644 index 9ebce8b1..00000000 --- a/docs/kubernetes/1.6/mailu/configmap.yaml +++ /dev/null @@ -1,153 +0,0 @@ - apiVersion: v1 - kind: ConfigMap - metadata: - name: mailu-config - namespace: mailu-mailserver - data: - # Mailu main configuration file - # - # Most configuration variables can be modified through the Web interface, - # these few settings must however be configured before starting the mail - # server and require a restart upon change. - - ################################### - # Common configuration variables - ################################### - - # Set this to the path where Mailu data and configuration is stored - ROOT: "/mailu" - - # Mailu version to run (1.0, 1.1, etc. or master) - VERSION: "master" - - # Set to a randomly generated 16 bytes string - SECRET_KEY: "YourKeyHere" - - # Address where listening ports should bind - BIND_ADDRESS4: "127.0.0.1" - #BIND_ADDRESS6: "::1" - - # Main mail domain - DOMAIN: "example.com" - - # Hostnames for this server, separated with comas - HOSTNAMES: "mail.example.com" - - # Postmaster local part (will append the main mail domain) - POSTMASTER: "admin" - - # Choose how secure connections will behave (value: letsencrypt, cert, notls, mail, mail-letsencrypt) - TLS_FLAVOR: "cert" - - # Authentication rate limit (per source IP address) - AUTH_RATELIMIT: "10/minute;1000/hour" - - # Opt-out of statistics, replace with "True" to opt out - DISABLE_STATISTICS: "False" - - ################################### - # Optional features - ################################### - - # Expose the admin interface (value: true, false) - ADMIN: "true" - # Run the admin interface in debug mode - #DEBUG: "True" - - # Choose which webmail to run if any (values: roundcube, rainloop, none) - WEBMAIL: "roundcube" - - # Dav server implementation (value: radicale, none) - WEBDAV: "radicale" - - # Antivirus solution (value: clamav, none) - ANTIVIRUS: "clamav" - - ################################### - # Mail settings - ################################### - - # Message size limit in bytes - # Default: accept messages up to 50MB - MESSAGE_SIZE_LIMIT: "50000000" - - # Networks granted relay permissions, make sure that you include your Docker - # internal network (default to 172.17.0.0/16) - # For kubernetes this is the CIDR of the pod network - RELAYNETS: "10.2.0.0/16" - POD_ADDRESS_RANGE: "10.2.0.0/16" - - - # Will relay all outgoing mails if configured - #RELAYHOST= - - # This part is needed for the XCLIENT login for postfix. This should be the POD ADDRESS range - FRONT_ADDRESS: "front.mailu-mailserver.svc.cluster.local" - - # Fetchmail delay - FETCHMAIL_DELAY: "600" - - # Recipient delimiter, character used to delimiter localpart from custom address part - # e.g. localpart+custom@domain;tld - RECIPIENT_DELIMITER: "+" - - # DMARC rua and ruf email - DMARC_RUA: "root" - DMARC_RUF: "root" - - # Welcome email, enable and set a topic and body if you wish to send welcome - # emails to all users. - WELCOME: "false" - WELCOME_SUBJECT: "Welcome to your new email account" - WELCOME_BODY: "Welcome to your new email account, if you can read this, then it is configured properly!" - - ################################### - # Web settings - ################################### - - # Path to the admin interface if enabled - WEB_ADMIN: "/admin" - - # Path to the webmail if enabled - WEB_WEBMAIL: "/webmail" - - # Website name - SITENAME: "AppSynth" - - # Linked Website URL - WEBSITE: "https://example.com" - - # Registration reCaptcha settings (warning, this has some privacy impact) - # RECAPTCHA_PUBLIC_KEY= - # RECAPTCHA_PRIVATE_KEY= - - # Domain registration, uncomment to enable - # DOMAIN_REGISTRATION=true - - ################################### - # Advanced settings - ################################### - - # Docker-compose project name, this will prepended to containers names. - COMPOSE_PROJECT_NAME: "mailu" - - # Default password scheme used for newly created accounts and changed passwords - # (value: SHA512-CRYPT, SHA256-CRYPT, MD5-CRYPT, CRYPT) - PASSWORD_SCHEME: "SHA512-CRYPT" - - # Header to take the real ip from - #REAL_IP_HEADER: - - # IPs for nginx set_real_ip_from (CIDR list separated by commas) - #REAL_IP_FROM: - - # Host settings - HOST_IMAP: "imap.mailu-mailserver.svc.cluster.local" - HOST_POP3: "imap.mailu-mailserver.svc.cluster.local" - HOST_SMTP: "smtp.mailu-mailserver.svc.cluster.local" - HOST_AUTHSMTP: "smtp.mailu-mailserver.svc.cluster.local" - HOST_WEBMAIL: "webmail.mailu-mailserver.svc.cluster.local" - HOST_ADMIN: "admin.mailu-mailserver.svc.cluster.local" - HOST_WEBDAV: "webdav.mailu-mailserver.svc.cluster.local:5232" - HOST_ANTISPAM: "antispam.mailu-mailserver.svc.cluster.local:11332" - HOST_REDIS: "redis.mailu-mailserver.svc.cluster.local" diff --git a/docs/kubernetes/1.6/mailu/fetchmail.yaml b/docs/kubernetes/1.6/mailu/fetchmail.yaml deleted file mode 100644 index cf3271e7..00000000 --- a/docs/kubernetes/1.6/mailu/fetchmail.yaml +++ /dev/null @@ -1,39 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-fetchmail - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-fetchmail - role: mail - tier: backend - spec: - containers: - - name: fetchmail - image: mailu/fetchmail:master - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - volumeMounts: - - name: maildata - mountPath: /data - subPath: maildata - ports: - - containerPort: 5232 - - containerPort: 80 - resources: - requests: - memory: 100Mi - cpu: 100m - limits: - memory: 100Mi - cpu: 100m - volumes: - - name: maildata - persistentVolumeClaim: - claimName: mail-storage \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/front.yaml b/docs/kubernetes/1.6/mailu/front.yaml deleted file mode 100644 index e25ac828..00000000 --- a/docs/kubernetes/1.6/mailu/front.yaml +++ /dev/null @@ -1,129 +0,0 @@ - -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-front - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-front - role: mail - tier: backend - spec: - restartPolicy: Always - terminationGracePeriodSeconds: 60 - containers: - - name: front - image: mailu/nginx:latest - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - volumeMounts: - - name: certs - mountPath: /certs - ports: - - name: http - containerPort: 80 - protocol: TCP - - name: https - containerPort: 443 - protocol: TCP - - name: pop3 - containerPort: 110 - protocol: TCP - - name: pop3s - containerPort: 995 - protocol: TCP - - name: imap - containerPort: 143 - protocol: TCP - - name: imaps - containerPort: 993 - protocol: TCP - - name: smtp - containerPort: 25 - protocol: TCP - - name: smtp-auth - containerPort: 10025 - protocol: TCP - - name: imap-auth - containerPort: 10143 - protocol: TCP - - name: smtps - containerPort: 465 - protocol: TCP - - name: smtpd - containerPort: 587 - protocol: TCP - - name: auth - containerPort: 8000 - protocol: TCP - resources: - requests: - memory: 100Mi - cpu: 100m - limits: - memory: 200Mi - cpu: 200m - volumes: - - 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: front - namespace: mailu-mailserver - labels: - app: mailu-admin - role: mail - tier: backend -spec: - selector: - app: mailu-front - role: mail - tier: backend - ports: - - name: http - port: 80 - protocol: TCP - - name: https - port: 443 - protocol: TCP - - name: pop3 - port: 110 - protocol: TCP - - name: pop3s - port: 995 - protocol: TCP - - name: imap - port: 143 - protocol: TCP - - name: imaps - port: 993 - protocol: TCP - - name: smtp - port: 25 - protocol: TCP - - name: smtps - port: 465 - protocol: TCP - - name: smtpd - port: 587 - protocol: TCP - - name: smtp-auth - port: 10025 - protocol: TCP - - name: imap-auth - port: 10143 - protocol: TCP diff --git a/docs/kubernetes/1.6/mailu/imap.yaml b/docs/kubernetes/1.6/mailu/imap.yaml deleted file mode 100644 index 069b7730..00000000 --- a/docs/kubernetes/1.6/mailu/imap.yaml +++ /dev/null @@ -1,80 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-imap - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-imap - role: mail - tier: backend - spec: - containers: - - name: imap - image: mailu/dovecot:master - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - volumeMounts: - - mountPath: /data - name: maildata - subPath: maildata - - mountPath: /mail - name: maildata - subPath: mailstate - - mountPath: /overrides - name: maildata - subPath: overrides - ports: - - containerPort: 2102 - - containerPort: 2525 - - containerPort: 143 - - containerPort: 993 - - containerPort: 4190 - resources: - requests: - memory: 500Mi - cpu: 500m - limits: - memory: 1Gi - cpu: 1000m - volumes: - - name: maildata - persistentVolumeClaim: - claimName: mail-storage ---- -apiVersion: v1 -kind: Service -metadata: - name: imap - namespace: mailu-mailserver - 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 \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/ingress-ssl.yaml b/docs/kubernetes/1.6/mailu/ingress-ssl.yaml deleted file mode 100644 index 61ae3cf7..00000000 --- a/docs/kubernetes/1.6/mailu/ingress-ssl.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: mailu-ssl-ingress - namespace: mailu-mailserver - annotations: - kubernetes.io/ingress.class: tectonic - kubernetes.io/tls-acme: "true" - nginx.ingress.kubernetes.io/proxy-body-size: "0" - ingress.kubernetes.io/ssl-redirect: "true" - # Replace letsencrypt-prod with the name of the certificate issuer - certmanager.k8s.io/cluster-issuer: letsencrypt-prod - #ingress.kubernetes.io/rewrite-target: "/" - #ingress.kubernetes.io/app-root: "/ui" - #ingress.kubernetes.io/follow-redirects: "true" - 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: "/" - backend: - serviceName: front - servicePort: 80 \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/pvc.yaml b/docs/kubernetes/1.6/mailu/pvc.yaml deleted file mode 100644 index 0ec2852f..00000000 --- a/docs/kubernetes/1.6/mailu/pvc.yaml +++ /dev/null @@ -1,27 +0,0 @@ -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: redis-hdd - namespace: mailu-mailserver - annotations: - volume.beta.kubernetes.io/storage-class: "glusterblock-hdd" -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: mail-storage - namespace: mailu-mailserver - annotations: - volume.beta.kubernetes.io/storage-class: "gluster-heketi-hdd" -spec: - accessModes: - - ReadWriteMany - resources: - requests: - storage: 100Gi diff --git a/docs/kubernetes/1.6/mailu/rbac.yaml b/docs/kubernetes/1.6/mailu/rbac.yaml deleted file mode 100644 index 33255130..00000000 --- a/docs/kubernetes/1.6/mailu/rbac.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: mailu-mailserver \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/redis.yaml b/docs/kubernetes/1.6/mailu/redis.yaml deleted file mode 100644 index d6bb1eb8..00000000 --- a/docs/kubernetes/1.6/mailu/redis.yaml +++ /dev/null @@ -1,56 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-redis - namespace: mailu-mailserver -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 - resources: - requests: - memory: 200Mi - cpu: 100m - limits: - memory: 300Mi - cpu: 200m - volumes: - - name: redisdata - persistentVolumeClaim: - claimName: redis-hdd ---- - -apiVersion: v1 -kind: Service -metadata: - name: redis - namespace: mailu-mailserver - labels: - app: mailu-redis - role: mail - tier: backend -spec: - selector: - app: mailu-redis - role: mail - tier: backend - ports: - - name: redis - port: 6379 - protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/security.yaml b/docs/kubernetes/1.6/mailu/security.yaml deleted file mode 100644 index c1c1ac0b..00000000 --- a/docs/kubernetes/1.6/mailu/security.yaml +++ /dev/null @@ -1,110 +0,0 @@ - -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-security - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-security - role: mail - tier: backend - spec: - containers: - - name: antispam - image: mailu/rspamd:master - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - resources: - requests: - memory: 100Mi - cpu: 100m - limits: - memory: 200Mi - cpu: 200m - ports: - - name: antispam - containerPort: 11332 - protocol: TCP - volumeMounts: - - name: filter - subPath: filter - mountPath: /var/lib/rspamd - - name: filter - mountPath: /dkim - subPath: dkim - - name: filter - mountPath: /etc/rspamd/override.d - subPath: rspamd-overrides - - name: antivirus - image: mailu/clamav:master - imagePullPolicy: Always - resources: - requests: - memory: 1Gi - cpu: 1000m - limits: - memory: 2Gi - cpu: 1000m - envFrom: - - configMapRef: - name: mailu-config - ports: - - name: antivirus - containerPort: 3310 - protocol: TCP - volumeMounts: - - name: filter - subPath: filter - mountPath: /data - volumes: - - name: filter - persistentVolumeClaim: - claimName: mail-storage - ---- - -apiVersion: v1 -kind: Service -metadata: - name: antispam - namespace: mailu-mailserver - labels: - app: mailu-antispam - role: mail - tier: backend -spec: - selector: - app: mailu-security - role: mail - tier: backend - ports: - - name: antispam - port: 11332 - protocol: TCP - ---- - -apiVersion: v1 -kind: Service -metadata: - name: antivirus - namespace: mailu-mailserver - labels: - app: mailu-antivirus - role: mail - tier: backend -spec: - selector: - app: mailu-security - role: mail - tier: backend - ports: - - name: antivirus - port: 3310 - protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/smtp.yaml b/docs/kubernetes/1.6/mailu/smtp.yaml deleted file mode 100644 index 454b8ed7..00000000 --- a/docs/kubernetes/1.6/mailu/smtp.yaml +++ /dev/null @@ -1,80 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-smtp - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-smtp - role: mail - tier: backend - spec: - containers: - - name: smtp - image: mailu/postfix:master - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - resources: - requests: - memory: 500Mi - cpu: 200m - limits: - memory: 1Gi - cpu: 500m - volumeMounts: - - mountPath: /data - name: maildata - subPath: maildata - - mountPath: /overrides - name: maildata - subPath: overrides - ports: - - name: smtp - containerPort: 25 - protocol: TCP - - name: smtp-ssl - containerPort: 465 - protocol: TCP - - name: smtp-starttls - containerPort: 587 - protocol: TCP - - name: smtp-auth - containerPort: 10025 - protocol: TCP - volumes: - - name: maildata - persistentVolumeClaim: - claimName: mail-storage ---- -apiVersion: v1 -kind: Service -metadata: - name: smtp - namespace: mailu-mailserver - 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 - - name: smtp-auth - port: 10025 - protocol: TCP diff --git a/docs/kubernetes/1.6/mailu/static-ips.yaml b/docs/kubernetes/1.6/mailu/static-ips.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/kubernetes/1.6/mailu/webdav.yaml b/docs/kubernetes/1.6/mailu/webdav.yaml deleted file mode 100644 index 07b7733c..00000000 --- a/docs/kubernetes/1.6/mailu/webdav.yaml +++ /dev/null @@ -1,63 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-webdav - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-webdav - role: mail - tier: backend - spec: - containers: - - name: radicale - image: mailu/radicale:master - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - volumeMounts: - - mountPath: /data - name: maildata - subPath: dav - ports: - - containerPort: 5232 - - containerPort: 80 - resources: - requests: - memory: 100Mi - cpu: 100m - limits: - memory: 100Mi - cpu: 100m - volumes: - - name: maildata - persistentVolumeClaim: - claimName: mail-storage ---- - -apiVersion: v1 -kind: Service -metadata: - name: webdav - namespace: mailu-mailserver - labels: - app: mailu-webdav - role: mail - tier: backend -spec: - selector: - app: mailu-webdav - role: mail - tier: backend - ports: - ports: - - name: http - port: 80 - protocol: TCP - - name: http-ui - port: 5232 - protocol: TCP \ No newline at end of file diff --git a/docs/kubernetes/1.6/mailu/webmail.yaml b/docs/kubernetes/1.6/mailu/webmail.yaml deleted file mode 100644 index 81798782..00000000 --- a/docs/kubernetes/1.6/mailu/webmail.yaml +++ /dev/null @@ -1,59 +0,0 @@ - -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: mailu-roundcube - namespace: mailu-mailserver -spec: - replicas: 1 - template: - metadata: - labels: - app: mailu-roundcube - role: mail - tier: frontend - spec: - containers: - - name: roundcube - image: mailu/roundcube:1.5 - imagePullPolicy: Always - envFrom: - - configMapRef: - name: mailu-config - resources: - requests: - memory: 100Mi - cpu: 100m - limits: - memory: 200Mi - cpu: 200m - volumeMounts: - - mountPath: /data - name: maildata - subPath: webmail - ports: - - containerPort: 80 - volumes: - - name: maildata - persistentVolumeClaim: - claimName: mail-storage ---- -apiVersion: v1 -kind: Service -metadata: - name: webmail - namespace: mailu-mailserver - labels: - app: mailu-roundcube - role: mail - tier: frontend -spec: - selector: - app: mailu-roundcube - role: mail - tier: frontend - ports: - ports: - - name: http - port: 80 - protocol: TCP diff --git a/docs/kubernetes/1.6/nginx/default-http-backend.yaml b/docs/kubernetes/1.6/nginx/default-http-backend.yaml deleted file mode 100644 index 097fe7c5..00000000 --- a/docs/kubernetes/1.6/nginx/default-http-backend.yaml +++ /dev/null @@ -1,55 +0,0 @@ -apiVersion: extensions/v1beta1 -kind: Deployment -metadata: - name: default-http-backend - labels: - app: default-http-backend - namespace: kube-ingress -spec: - replicas: 1 - selector: - matchLabels: - app: default-http-backend - template: - metadata: - labels: - app: default-http-backend - spec: - terminationGracePeriodSeconds: 60 - containers: - - name: default-http-backend - # Any image is permissible as long as: - # 1. It serves a 404 page at / - # 2. It serves 200 on a /healthz endpoint - image: gcr.io/google_containers/defaultbackend:1.4 - livenessProbe: - httpGet: - path: /healthz - port: 8080 - scheme: HTTP - initialDelaySeconds: 30 - timeoutSeconds: 5 - ports: - - containerPort: 8080 - resources: - limits: - cpu: 10m - memory: 20Mi - requests: - cpu: 10m - memory: 20Mi ---- - -apiVersion: v1 -kind: Service -metadata: - name: default-http-backend - namespace: kube-ingress - labels: - app: default-http-backend -spec: - ports: - - port: 80 - targetPort: 8080 - selector: - app: default-http-backend \ No newline at end of file diff --git a/docs/kubernetes/1.6/nginx/nginx-ingress.yaml b/docs/kubernetes/1.6/nginx/nginx-ingress.yaml deleted file mode 100644 index 90b24f24..00000000 --- a/docs/kubernetes/1.6/nginx/nginx-ingress.yaml +++ /dev/null @@ -1,139 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - # keep it under 24 chars - name: appsynth-lb - namespace: kube-ingress - labels: - k8s-app: appsynth-lb - component: ingress-controller -spec: - type: ClusterIP - selector: - k8s-app: appsynth-lb - component: ingress-controller - ports: - - name: http - protocol: TCP - port: 80 - targetPort: 80 - - name: https - protocol: TCP - port: 443 - targetPort: 443 ---- -kind: ConfigMap -apiVersion: v1 -metadata: - name: udp-services - namespace: kube-ingress - ---- -kind: ConfigMap -apiVersion: v1 -metadata: - name: tcp-services - namespace: kube-ingress -data: - 25: "mailu-mailserver/front:25" - 110: "mailu-mailserver/front:110" - 465: "mailu-mailserver/front:465" - 587: "mailu-mailserver/front:587" - 143: "mailu-mailserver/front:143" - 993: "mailu-mailserver/front:993" - 995: "mailu-mailserver/front:995" - ---- -apiVersion: v1 -data: - enable-vts-status: "true" -kind: ConfigMap -metadata: - name: nginx-ingress-lb-conf - namespace: kube-ingress ---- -apiVersion: apps/v1beta2 -kind: DaemonSet -metadata: - name: ingress-controller - namespace: kube-ingress - annotations: - prometheus.io/port: "10254" - prometheus.io/scrape: "true" - labels: - k8s-app: appsynth-lb - component: ingress-controller - type: nginx -spec: - updateStrategy: - rollingUpdate: - maxUnavailable: 1 - type: RollingUpdate - selector: - matchLabels: - k8s-app: appsynth-lb - component: ingress-controller - type: nginx - template: - metadata: - labels: - k8s-app: appsynth-lb - component: ingress-controller - type: nginx - spec: - serviceAccount: kube-nginx-ingress - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: node-role.kubernetes.io/master - operator: DoesNotExist - containers: - - name: nginx-ingress-lb - image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.16.2 - args: - - /nginx-ingress-controller - - --configmap=$(POD_NAMESPACE)/tectonic-custom-error - - --default-backend-service=$(POD_NAMESPACE)/default-http-backend - #- --default-ssl-certificate=tectonic-system/tectonic-ingress-tls-secret - - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services - - --udp-services-configmap=$(POD_NAMESPACE)/udp-services - - --annotations-prefix=ingress.kubernetes.io - - --enable-ssl-passthrough - - --ingress-class=tectonic - # use downward API - env: - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - ports: - - name: http - containerPort: 80 - hostPort: 80 - - name: https - containerPort: 443 - hostPort: 443 - readinessProbe: - httpGet: - path: /healthz - port: 10254 - scheme: HTTP - livenessProbe: - initialDelaySeconds: 10 - timeoutSeconds: 1 - httpGet: - path: /healthz - port: 10254 - scheme: HTTP - hostNetwork: true - nodeSelector: - node-role.kubernetes.io/node: "" - dnsPolicy: ClusterFirst - restartPolicy: Always - terminationGracePeriodSeconds: 60 diff --git a/docs/kubernetes/1.6/nginx/rbac.yaml b/docs/kubernetes/1.6/nginx/rbac.yaml deleted file mode 100644 index d3c01384..00000000 --- a/docs/kubernetes/1.6/nginx/rbac.yaml +++ /dev/null @@ -1,129 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: kube-ingress ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: kube-nginx-ingress - namespace: kube-ingress ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRole -metadata: - name: kube-nginx-ingress -rules: - - apiGroups: - - "" - resources: - - configmaps - - endpoints - - nodes - - pods - - secrets - verbs: - - list - - watch - - update - - apiGroups: - - "" - resources: - - nodes - verbs: - - get - - apiGroups: - - "" - resources: - - services - verbs: - - get - - list - - watch - - apiGroups: - - "extensions" - resources: - - ingresses - verbs: - - get - - list - - watch - - apiGroups: - - "" - resources: - - events - verbs: - - create - - patch - - apiGroups: - - "extensions" - resources: - - ingresses/status - verbs: - - update ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: Role -metadata: - name: kube-nginx-ingress - namespace: kube-ingress -rules: - - apiGroups: - - "" - resources: - - configmaps - - pods - - secrets - - namespaces - verbs: - - get - - apiGroups: - - "" - resources: - - configmaps - resourceNames: - - "ingress-controller-leader-nginx" - verbs: - - get - - update - - apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - apiGroups: - - "" - resources: - - endpoints - verbs: - - get - - create - - update ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: RoleBinding -metadata: - name: kube-nginx-ingress - namespace: kube-ingress -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: kube-nginx-ingress -subjects: - - kind: ServiceAccount - name: kube-nginx-ingress - namespace: kube-ingress ---- -apiVersion: rbac.authorization.k8s.io/v1beta1 -kind: ClusterRoleBinding -metadata: - name: kube-nginx-ingress -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: kube-nginx-ingress -subjects: - - kind: ServiceAccount - name: kube-nginx-ingress - namespace: kube-ingress \ No newline at end of file From ef55ca525c1286006c5090f4c653d133557851bb Mon Sep 17 00:00:00 2001 From: Hans Cornelis Date: Wed, 17 Oct 2018 07:48:52 +0200 Subject: [PATCH 18/39] Deleted conflicting merge files Signed-off-by: Hans Cornelis --- core/dovecot/Dockerfile_BACKUP_7007 | 19 ------------------- core/dovecot/Dockerfile_BASE_7007 | 14 -------------- core/dovecot/Dockerfile_LOCAL_7007 | 14 -------------- core/dovecot/Dockerfile_REMOTE_7007 | 15 --------------- 4 files changed, 62 deletions(-) delete mode 100644 core/dovecot/Dockerfile_BACKUP_7007 delete mode 100644 core/dovecot/Dockerfile_BASE_7007 delete mode 100644 core/dovecot/Dockerfile_LOCAL_7007 delete mode 100644 core/dovecot/Dockerfile_REMOTE_7007 diff --git a/core/dovecot/Dockerfile_BACKUP_7007 b/core/dovecot/Dockerfile_BACKUP_7007 deleted file mode 100644 index b5590a73..00000000 --- a/core/dovecot/Dockerfile_BACKUP_7007 +++ /dev/null @@ -1,19 +0,0 @@ -<<<<<<< HEAD -FROM alpine:3.7 -======= -FROM alpine:3.8 ->>>>>>> upstream/master - -RUN apk add --no-cache \ - dovecot dovecot-pigeonhole-plugin dovecot-fts-lucene rspamd-client \ - python3 py3-pip \ - && pip3 install --upgrade pip \ - && pip3 install jinja2 podop tenacity - -COPY conf /conf -COPY start.py /start.py - -EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp -VOLUME ["/data", "/mail"] - -CMD /start.py \ No newline at end of file diff --git a/core/dovecot/Dockerfile_BASE_7007 b/core/dovecot/Dockerfile_BASE_7007 deleted file mode 100644 index cacfe354..00000000 --- a/core/dovecot/Dockerfile_BASE_7007 +++ /dev/null @@ -1,14 +0,0 @@ -FROM alpine:edge - -RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \ - && apk add --no-cache \ - dovecot dovecot-sqlite dovecot-pigeonhole-plugin dovecot-pigeonhole-plugin-extdata \ - rspamd-client@testing python py-jinja2 - -COPY conf /conf -COPY sieve /var/lib/dovecot -COPY start.py /start.py - -EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp - -CMD /start.py diff --git a/core/dovecot/Dockerfile_LOCAL_7007 b/core/dovecot/Dockerfile_LOCAL_7007 deleted file mode 100644 index 29957921..00000000 --- a/core/dovecot/Dockerfile_LOCAL_7007 +++ /dev/null @@ -1,14 +0,0 @@ -FROM alpine:3.7 - -RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \ - && apk add --no-cache \ - dovecot dovecot-sqlite dovecot-pigeonhole-plugin dovecot-pigeonhole-plugin-extdata \ - rspamd-client@testing python py-jinja2 - -COPY conf /conf -COPY sieve /var/lib/dovecot -COPY start.py /start.py - -EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp - -CMD /start.py \ No newline at end of file diff --git a/core/dovecot/Dockerfile_REMOTE_7007 b/core/dovecot/Dockerfile_REMOTE_7007 deleted file mode 100644 index d8d4c55b..00000000 --- a/core/dovecot/Dockerfile_REMOTE_7007 +++ /dev/null @@ -1,15 +0,0 @@ -FROM alpine:3.8 - -RUN apk add --no-cache \ - dovecot dovecot-pigeonhole-plugin dovecot-fts-lucene rspamd-client \ - python3 py3-pip \ - && pip3 install --upgrade pip \ - && pip3 install jinja2 podop tenacity - -COPY conf /conf -COPY start.py /start.py - -EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp -VOLUME ["/data", "/mail"] - -CMD /start.py From b3c7c45140f4c8d1e019ecff9db5c5f623b6f8ff Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Wed, 17 Oct 2018 15:11:55 +0300 Subject: [PATCH 19/39] Added input form constraints --- setup/flavors/compose/docker-compose.yml | 4 ++-- setup/flavors/compose/mailu.env | 6 ++--- .../config.html} | 22 +++++++++++++------ .../templates/steps/{ => compose}/expose.html | 12 +++++++--- .../templates/steps/{ => compose}/flavor.html | 0 .../steps/{ => compose}/optional.html | 0 .../steps/{ => compose}/services.html | 21 ++++++++++++------ setup/templates/wizard.html | 10 ++++----- 8 files changed, 48 insertions(+), 27 deletions(-) rename setup/templates/steps/{initial-config.html => compose/config.html} (71%) rename setup/templates/steps/{ => compose}/expose.html (67%) rename setup/templates/steps/{ => compose}/flavor.html (100%) rename setup/templates/steps/{ => compose}/optional.html (100%) rename setup/templates/steps/{ => compose}/services.html (77%) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index 83a46169..8316e681 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -20,7 +20,7 @@ services: env_file: {{ env }} env: - TLS_FLAVOR={{ tls_flavor }} - - ADMIN={{ admin_enabled or 'no' }} + - ADMIN={{ admin_enabled or 'false' }} ports: {% for port in (80, 443, 25, 465, 587, 110, 995, 143, 993) %} {% if bind4 %} @@ -112,7 +112,7 @@ services: {% endif %} # Webmail - {% if webmail_enabled %} + {% if webmail_type != 'none' %} webmail: image: mailu/{{ webmail_type }}:{{ version }} restart: always diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index b1cded1c..77da5670 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -33,8 +33,9 @@ POSTMASTER={{ postmaster or 'admin'}} HOSTNAMES={{ hostnames }} # Authentication rate limit (per source IP address) -AUTH_RATELIMIT={% if auth_ratelimit_pm %}{{ auth_ratelimit_pm }}/minute;{% endif %} -{% if auth_ratelimit_ph %}{{ auth_ratelimit_ph }}/hour{% endif %} +{% 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 or 'False' }} @@ -47,7 +48,6 @@ DISABLE_STATISTICS={{ disable_statistics or 'False' }} #ADMIN={{ admin_enabled or 'false' }} #Chose which webmail to run if any -#WEBMAIL_ENABLED={{ webmail_enabled or 'false' }} #WEBMAIL={{ webmail_type or 'none' }} #Antivirus solution diff --git a/setup/templates/steps/initial-config.html b/setup/templates/steps/compose/config.html similarity index 71% rename from setup/templates/steps/initial-config.html rename to setup/templates/steps/compose/config.html index c16d4c13..f5a39a5a 100644 --- a/setup/templates/steps/initial-config.html +++ b/setup/templates/steps/compose/config.html @@ -3,12 +3,15 @@
- + +
- + +
@@ -20,7 +23,7 @@
- +
@@ -35,8 +38,11 @@
-

/minute; - /hour

+ +

/minute; + /hour

@@ -48,12 +54,14 @@
- +
- + +
{% endcall %} diff --git a/setup/templates/steps/expose.html b/setup/templates/steps/compose/expose.html similarity index 67% rename from setup/templates/steps/expose.html rename to setup/templates/steps/compose/expose.html index 372ebddc..e0aa8fee 100644 --- a/setup/templates/steps/expose.html +++ b/setup/templates/steps/compose/expose.html @@ -14,12 +14,16 @@ avoid generic all-interfaces addresses like 0.0.0.0 or :: - + +
- + +

You server will be available under a main hostname but may expose multiple public @@ -28,6 +32,8 @@ hostnames in its MX record. Hostnames must be coma-separated.

- + +
{% endcall %} diff --git a/setup/templates/steps/flavor.html b/setup/templates/steps/compose/flavor.html similarity index 100% rename from setup/templates/steps/flavor.html rename to setup/templates/steps/compose/flavor.html diff --git a/setup/templates/steps/optional.html b/setup/templates/steps/compose/optional.html similarity index 100% rename from setup/templates/steps/optional.html rename to setup/templates/steps/compose/optional.html diff --git a/setup/templates/steps/services.html b/setup/templates/steps/compose/services.html similarity index 77% rename from setup/templates/steps/services.html rename to setup/templates/steps/compose/services.html index ed529c83..d8ec8106 100644 --- a/setup/templates/steps/services.html +++ b/setup/templates/steps/compose/services.html @@ -18,16 +18,23 @@ manage your email domains, users, etc.

email client. These do add some complexity but provide an easier way of accessing messages for beginner users.

+
-
-
- -
+ + + + +
+

-
- {{ macros.radio("webmail_type", "roundcube", "RoundCube", "popular Webmail running on top of PHP") }} - {{ macros.radio("webmail_type", "rainloop", "Rainloop", "lightweight Webmail based on PHP, no database") }} +
+ +
diff --git a/setup/templates/wizard.html b/setup/templates/wizard.html index 5a15af6f..1c85a0ad 100644 --- a/setup/templates/wizard.html +++ b/setup/templates/wizard.html @@ -9,11 +9,11 @@ {% endcall %}
- {% include "steps/initial-config.html" %} - {% include "steps/flavor.html" %} - {% include "steps/expose.html" %} - {% include "steps/services.html" %} - + {% include "steps/compose/flavor.html" %} + {% include "steps/compose/config.html" %} + {% include "steps/compose/services.html" %} + {% include "steps/compose/expose.html" %} +
From 6b6cbcf977002f768827389f035ab45fde1c4c15 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Wed, 17 Oct 2018 15:38:51 +0300 Subject: [PATCH 20/39] Modified variables in .env file --- setup/flavors/compose/mailu.env | 27 ++++++++++++++--------- setup/templates/steps/compose/config.html | 2 +- setup/templates/steps/compose/expose.html | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 77da5670..a577f979 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -65,26 +65,24 @@ DISABLE_STATISTICS={{ disable_statistics or 'False' }} # 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 @@ -94,6 +92,12 @@ WELCOME_SUBJECT={{ welcome_subject }} WELCOME_BODY={{ welcome_body }} {% 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 }} + {% if domain_registration %} # Domain registration (remove to disable) DOMAIN_REGISTRATION=true @@ -125,13 +129,14 @@ WEBSITE={{ website }} # Advanced settings ################################### -{% if password_scheme %} # Specific password storage scheme -PASSWORD_SCHEME={{ password_scheme }} -{% endif %} +PASSWORD_SCHEME={{ password_scheme or 'SHA512-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/templates/steps/compose/config.html b/setup/templates/steps/compose/config.html index f5a39a5a..8d613d08 100644 --- a/setup/templates/steps/compose/config.html +++ b/setup/templates/steps/compose/config.html @@ -1,4 +1,4 @@ -{% call macros.panel("info", "Step 0 - Initial configuration") %} +{% call macros.panel("info", "Step 2 - Initial configuration") %}

Before starting some variables must be st

diff --git a/setup/templates/steps/compose/expose.html b/setup/templates/steps/compose/expose.html index e0aa8fee..6bc2f528 100644 --- a/setup/templates/steps/compose/expose.html +++ b/setup/templates/steps/compose/expose.html @@ -1,4 +1,4 @@ -{% call macros.panel("info", "Step 2 - expose Mailu to the world") %} +{% 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.

From cb1ed349bf15f13690416583816ff0f6a8b8c117 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Wed, 17 Oct 2018 16:46:20 +0300 Subject: [PATCH 21/39] Bug fixes --- setup/flavors/compose/docker-compose.yml | 10 ++-------- setup/flavors/compose/mailu.env | 8 ++++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/setup/flavors/compose/docker-compose.yml b/setup/flavors/compose/docker-compose.yml index 8316e681..3d84e595 100644 --- a/setup/flavors/compose/docker-compose.yml +++ b/setup/flavors/compose/docker-compose.yml @@ -2,7 +2,7 @@ # This file is auto-generated by the Mailu configuration wizard. # Please read the documentation before attempting any change. -version: '3.7' +version: '3.6' services: @@ -18,7 +18,7 @@ services: image: mailu/nginx:{{ version }} restart: always env_file: {{ env }} - env: + environment: - TLS_FLAVOR={{ tls_flavor }} - ADMIN={{ admin_enabled or 'false' }} ports: @@ -30,10 +30,8 @@ services: - "{{ bind6 }}:{{ port }}:{{ port }}" {% endif %} {% endfor %} - {% if flavor in ('cert', 'mail') %} volumes: - "{{ root }}/certs:/certs" - {% endif %} admin: image: mailu/admin:{{ version }} @@ -54,7 +52,6 @@ services: restart: always env_file: {{ env }} volumes: - - "{{ root }}/data:/data" - "{{ root }}/mail:/mail" - "{{ root }}/overrides:/overrides" depends_on: @@ -65,7 +62,6 @@ services: restart: always env_file: {{ env }} volumes: - - "{{ root }}/data:/data" - "{{ root }}/overrides:/overrides" depends_on: - front @@ -107,8 +103,6 @@ services: image: mailu/fetchmail:{{ version }} restart: always env_file: {{ env }} - volumes: - - "{{ root }}/data:/data" {% endif %} # Webmail diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index a577f979..55def163 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -21,7 +21,7 @@ SECRET_KEY={{ secret(16) }} # PUBLIC_IPV6= {{ bind6 }} (default: ::1) # Main mail domain -# DOMAIN={{ domain }} +DOMAIN={{ domain }} # Mail address of the postmaster POSTMASTER={{ postmaster or 'admin'}} @@ -48,16 +48,16 @@ DISABLE_STATISTICS={{ disable_statistics or 'False' }} #ADMIN={{ admin_enabled or 'false' }} #Chose which webmail to run if any -#WEBMAIL={{ webmail_type or 'none' }} +WEBMAIL={{ webmail_type }} #Antivirus solution #ANTIVIRUS={{ antivirus_enabled or 'none' }} #Antispam solution -#ANTISPAM={{ antispam_enabled or 'none'}} +ANTISPAM={{ antispam_enabled or 'none'}} #Dav server implementation -#WEBDAV={{ webdav_enabled or 'none' }} +WEBDAV={{ webdav_enabled or 'none' }} ################################### # Server behavior From 7c0f5b20d6e196f71cda5d4d38773810a15cdaf1 Mon Sep 17 00:00:00 2001 From: Ionut Filip Date: Wed, 17 Oct 2018 17:54:37 +0300 Subject: [PATCH 22/39] Bug fixes --- setup/templates/steps/compose/expose.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/templates/steps/compose/expose.html b/setup/templates/steps/compose/expose.html index 6bc2f528..df121c7d 100644 --- a/setup/templates/steps/compose/expose.html +++ b/setup/templates/steps/compose/expose.html @@ -15,7 +15,7 @@ avoid generic all-interfaces addresses like 0.0.0.0 or :: -
@@ -23,7 +23,7 @@ avoid generic all-interfaces addresses like 0.0.0.0 or ::IPv6 listen address + pattern="^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$">

You server will be available under a main hostname but may expose multiple public From ed53d655d3977c8e7794ec66eeac38881c541cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 17 Oct 2018 18:38:10 +0300 Subject: [PATCH 23/39] Extend documentation in download page. Small cleanup in env. --- setup/flavors/compose/mailu.env | 2 +- setup/flavors/compose/setup.html | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/setup/flavors/compose/mailu.env b/setup/flavors/compose/mailu.env index 55def163..fba5bee8 100644 --- a/setup/flavors/compose/mailu.env +++ b/setup/flavors/compose/mailu.env @@ -24,7 +24,7 @@ SECRET_KEY={{ secret(16) }} DOMAIN={{ domain }} # Mail address of the postmaster -POSTMASTER={{ postmaster or 'admin'}} +POSTMASTER={{ postmaster }} #Chose how secure connections will behave: #TLS_FLAVOR={{ tls_flavor }} diff --git a/setup/flavors/compose/setup.html b/setup/flavors/compose/setup.html index 3c190c9c..d5f7abc5 100644 --- a/setup/flavors/compose/setup.html +++ b/setup/flavors/compose/setup.html @@ -11,8 +11,8 @@ in a project directory. First create your project directory.

to read and check the configuration variables generated by the wizard.

cd {{ root }}
-wget {{ url_for('.file', uid=uid, filepath='docker-compose.yml', _external=True) }}
-wget {{ url_for('.file', uid=uid, filepath='mailu.env', _external=True) }}
+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 %} @@ -33,4 +33,17 @@ command.

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 the the admin interface to change the password for a safe one, at +{% if admin_enabled %} +one of the hostnames ({{ hostnames }}){{ 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 %} From 5679d355aafa14cdce652e5dc50a3e053f1e1a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Wed, 17 Oct 2018 18:45:09 +0300 Subject: [PATCH 24/39] Avoid binding conflicts on production servers --- setup/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/docker-compose.yml b/setup/docker-compose.yml index 30966167..e91332e1 100644 --- a/setup/docker-compose.yml +++ b/setup/docker-compose.yml @@ -9,6 +9,6 @@ services: setup: image: mailu/setup ports: - - "80:80" + - "8000:80" build: . From adfadab4cf4d749d6bf95f0b9bd420fa3bc93094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Thu, 18 Oct 2018 12:56:16 +0300 Subject: [PATCH 25/39] Load steps after setting flavor --- setup/server.py | 5 +++++ setup/templates/macros.html | 4 ++-- setup/templates/steps/{compose => }/flavor.html | 8 ++++---- setup/templates/wizard.html | 17 +++++++++++------ 4 files changed, 22 insertions(+), 12 deletions(-) rename setup/templates/steps/{compose => }/flavor.html (81%) diff --git a/setup/server.py b/setup/server.py index ddeafd90..4e29fe9e 100644 --- a/setup/server.py +++ b/setup/server.py @@ -65,6 +65,11 @@ 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() + return flask.render_template('wizard.html', flavor=data["flavor"]) + @bp.route("/submit", methods=["POST"]) def submit(): data = flask.request.form.copy() 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) %}