diff --git a/core/admin/Dockerfile b/core/admin/Dockerfile index 083bec80..315b2e39 100644 --- a/core/admin/Dockerfile +++ b/core/admin/Dockerfile @@ -1,24 +1,28 @@ -FROM python:3-alpine - +FROM alpine:3.8 +# python3 shared with most images +RUN apk add --no-cache \ + python3 py3-pip \ + && pip3 install --upgrade pip +# Image specific layers under this line RUN mkdir -p /app WORKDIR /app COPY requirements-prod.txt requirements.txt 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 add --no-cache --virtual build-dep openssl-dev libffi-dev python3-dev build-base \ + && pip3 install -r requirements.txt \ && apk del --no-cache build-dep COPY mailu ./mailu COPY migrations ./migrations COPY manage.py . -COPY start.sh /start.sh +COPY start.py /start.py RUN pybabel compile -d mailu/translations EXPOSE 80/tcp VOLUME ["/data"] -CMD ["/start.sh"] +CMD /start.py HEALTHCHECK CMD curl -f -L http://localhost/ui || exit 1 diff --git a/core/admin/start.py b/core/admin/start.py new file mode 100755 index 00000000..59c97686 --- /dev/null +++ b/core/admin/start.py @@ -0,0 +1,7 @@ +#!/usr/bin/python3 + +import os + +os.system("python3 manage.py advertise") +os.system("python3 manage.py db upgrade") +os.system("gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload mailu:app") diff --git a/core/admin/start.sh b/core/admin/start.sh deleted file mode 100755 index 8208e4a1..00000000 --- a/core/admin/start.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -python manage.py advertise -python manage.py db upgrade -gunicorn -w 4 -b :80 --access-logfile - --error-logfile - --preload mailu:app diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index da29756f..1d4f7b91 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -1,10 +1,16 @@ FROM alpine:3.8 - +# python3 shared with most images RUN apk add --no-cache \ - dovecot dovecot-pigeonhole-plugin dovecot-fts-lucene rspamd-client \ - bash python3 py3-pip \ - && pip3 install --upgrade pip \ - && pip3 install jinja2 podop tenacity + python3 py3-pip \ + && pip3 install --upgrade pip +# Shared layer between rspamd, postfix, dovecot, unbound and nginx +RUN pip3 install jinja2 +# Shared layer between rspamd, postfix, dovecot +RUN pip3 install tenacity +# Image specific layers under this line +RUN apk add --no-cache \ + dovecot dovecot-pigeonhole-plugin dovecot-fts-lucene rspamd-client bash \ + && pip3 install podop COPY conf /conf COPY start.py /start.py diff --git a/core/dovecot/start.py b/core/dovecot/start.py index b65b4db9..8bf66efd 100755 --- a/core/dovecot/start.py +++ b/core/dovecot/start.py @@ -21,15 +21,12 @@ def start_podop(): convert = lambda src, dst: open(dst, "w").write(jinja2.Template(open(src).read()).render(**os.environ)) -@retry(stop=tenacity.stop_after_attempt(100), wait=tenacity.wait_random(min=2, max=5)) -def resolve(): - os.environ["FRONT_ADDRESS"] = socket.gethostbyname(os.environ.get("FRONT_ADDRESS", "front")) - os.environ["REDIS_ADDRESS"] = socket.gethostbyname(os.environ.get("REDIS_ADDRESS", "redis")) - if os.environ["WEBMAIL"] != "none": - os.environ["WEBMAIL_ADDRESS"] = socket.gethostbyname(os.environ.get("WEBMAIL_ADDRESS", "webmail")) - # Actual startup script -resolve() +resolve = retry(socket.gethostbyname, stop=tenacity.stop_after_attempt(100), wait=tenacity.wait_random(min=2, max=5)) +os.environ["FRONT_ADDRESS"] = resolve(os.environ.get("FRONT_ADDRESS", "front")) +os.environ["REDIS_ADDRESS"] = resolve(os.environ.get("REDIS_ADDRESS", "redis")) +if os.environ["WEBMAIL"] != "none": + os.environ["WEBMAIL_ADDRESS"] = resolve(os.environ.get("WEBMAIL_ADDRESS", "webmail")) for dovecot_file in glob.glob("/conf/*.conf"): convert(dovecot_file, os.path.join("/etc/dovecot", os.path.basename(dovecot_file))) diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 00ecf84e..7181487e 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -1,9 +1,13 @@ FROM alpine:3.8 - +# python3 shared with most images +RUN apk add --no-cache \ + python3 py3-pip \ + && pip3 install --upgrade pip +# Shared layer between rspamd, postfix, dovecot, unbound and nginx +RUN pip3 install jinja2 +# Image specific layers under this line 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 + && pip3 install idna requests COPY conf /conf COPY *.py / diff --git a/core/nginx/config.py b/core/nginx/config.py index 33071d01..07b7ea32 100755 --- a/core/nginx/config.py +++ b/core/nginx/config.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import jinja2 import os diff --git a/core/nginx/letsencrypt.py b/core/nginx/letsencrypt.py index b6044eca..3fe8ea92 100755 --- a/core/nginx/letsencrypt.py +++ b/core/nginx/letsencrypt.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import os import time diff --git a/core/nginx/start.py b/core/nginx/start.py index b63b64a2..7c5fa71e 100755 --- a/core/nginx/start.py +++ b/core/nginx/start.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import os import subprocess diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index e0529e01..ac9c8159 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -1,9 +1,16 @@ FROM alpine:3.8 +# python3 shared with most images +RUN apk add --no-cache \ + python3 py3-pip \ + && pip3 install --upgrade pip +# Shared layer between rspamd, postfix, dovecot, unbound and nginx +RUN pip3 install jinja2 +# Shared layer between rspamd, postfix, dovecot +RUN pip3 install tenacity +# Image specific layers under this line RUN apk add --no-cache postfix postfix-pcre rsyslog \ - python3 py3-pip \ - && pip3 install --upgrade pip \ - && pip3 install jinja2 podop tenacity + && pip3 install podop COPY conf /conf COPY start.py /start.py diff --git a/core/postfix/start.py b/core/postfix/start.py index decc17b9..b3bb328d 100755 --- a/core/postfix/start.py +++ b/core/postfix/start.py @@ -24,12 +24,10 @@ def start_podop(): convert = lambda src, dst: open(dst, "w").write(jinja2.Template(open(src).read()).render(**os.environ)) -@retry(stop=tenacity.stop_after_attempt(100), wait=tenacity.wait_random(min=2, max=5)) -def resolve(): - os.environ["FRONT_ADDRESS"] = socket.gethostbyname(os.environ.get("FRONT_ADDRESS", "front")) - # Actual startup script -resolve() +resolve = retry(socket.gethostbyname, stop=tenacity.stop_after_attempt(100), wait=tenacity.wait_random(min=2, max=5)) + +os.environ["FRONT_ADDRESS"] = resolve(os.environ.get("FRONT_ADDRESS", "front")) os.environ["HOST_ANTISPAM"] = os.environ.get("HOST_ANTISPAM", "antispam:11332") os.environ["HOST_LMTP"] = os.environ.get("HOST_LMTP", "imap:2525") diff --git a/optional/clamav/Dockerfile b/optional/clamav/Dockerfile index 3a9bf4aa..b3df2d45 100644 --- a/optional/clamav/Dockerfile +++ b/optional/clamav/Dockerfile @@ -1,14 +1,18 @@ FROM alpine:3.8 - +# python3 shared with most images +RUN apk add --no-cache \ + python3 py3-pip \ + && pip3 install --upgrade pip +# Image specific layers under this line RUN apk add --no-cache clamav rsyslog wget clamav-libunrar COPY conf /etc/clamav -COPY start.sh /start.sh +COPY start.py /start.py COPY health.sh /health.sh EXPOSE 3310/tcp VOLUME ["/data"] -CMD ["/start.sh"] +CMD /start.py HEALTHCHECK CMD /health.sh diff --git a/optional/clamav/start.py b/optional/clamav/start.py new file mode 100755 index 00000000..d4701d2d --- /dev/null +++ b/optional/clamav/start.py @@ -0,0 +1,12 @@ +#!/usr/bin/python3 + +import os + +# Bootstrap the database if clamav is running for the first time +os.system("[ -f /data/main.cvd ] || freshclam") + +# Run the update daemon +os.system("freshclam -d -c 6") + +# Run clamav +os.system("clamd") diff --git a/optional/clamav/start.sh b/optional/clamav/start.sh deleted file mode 100755 index 214230fd..00000000 --- a/optional/clamav/start.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Bootstrap the database if clamav is running for the first time -[ -f /data/main.cvd ] || freshclam - -# Run the update daemon -freshclam -d -c 6 - -# Run clamav -clamd diff --git a/services/fetchmail/Dockerfile b/services/fetchmail/Dockerfile index 33f8a7de..52f794d5 100644 --- a/services/fetchmail/Dockerfile +++ b/services/fetchmail/Dockerfile @@ -1,7 +1,11 @@ -FROM python:3-alpine - +FROM alpine:3.8 +# python3 shared with most images +RUN apk add --no-cache \ + python3 py3-pip \ + && pip3 install --upgrade pip +# Image specific layers under this line RUN apk add --no-cache fetchmail ca-certificates \ - && pip install requests + && pip3 install requests COPY fetchmail.py /fetchmail.py USER fetchmail diff --git a/services/fetchmail/fetchmail.py b/services/fetchmail/fetchmail.py index 8e006f84..9b1bcc4f 100755 --- a/services/fetchmail/fetchmail.py +++ b/services/fetchmail/fetchmail.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python3 import time import os diff --git a/services/rspamd/Dockerfile b/services/rspamd/Dockerfile index 76731c9a..6d0cb5d0 100644 --- a/services/rspamd/Dockerfile +++ b/services/rspamd/Dockerfile @@ -1,8 +1,14 @@ FROM alpine:3.8 - -RUN apk add --no-cache python py-jinja2 rspamd rspamd-controller rspamd-proxy rspamd-fuzzy ca-certificates py-pip curl\ - && pip install --upgrade pip \ - && pip install tenacity +# python3 shared with most images +RUN apk add --no-cache \ + python3 py3-pip \ + && pip3 install --upgrade pip +# Shared layer between rspamd, postfix, dovecot, unbound and nginx +RUN pip3 install jinja2 +# Shared layer between rspamd, postfix, dovecot +RUN pip3 install tenacity +# Image specific layers under this line +RUN apk add --no-cache rspamd rspamd-controller rspamd-proxy rspamd-fuzzy ca-certificates curl RUN mkdir /run/rspamd diff --git a/services/rspamd/start.py b/services/rspamd/start.py index b979517e..0b3c48a8 100755 --- a/services/rspamd/start.py +++ b/services/rspamd/start.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 import jinja2 import os @@ -9,12 +9,11 @@ from tenacity import retry convert = lambda src, dst: open(dst, "w").write(jinja2.Template(open(src).read()).render(**os.environ)) -@retry(stop=tenacity.stop_after_attempt(100), wait=tenacity.wait_random(min=2, max=5)) -def resolve(): - os.environ["FRONT_ADDRESS"] = socket.gethostbyname(os.environ.get("FRONT_ADDRESS", "front")) - # Actual startup script -resolve() +resolve = retry(socket.gethostbyname, stop=tenacity.stop_after_attempt(100), wait=tenacity.wait_random(min=2, max=5)) + +os.environ["FRONT_ADDRESS"] = resolve(os.environ.get("FRONT_ADDRESS", "front")) + if "HOST_REDIS" not in os.environ: os.environ["HOST_REDIS"] = "redis" for rspamd_file in glob.glob("/conf/*"): diff --git a/services/unbound/Dockerfile b/services/unbound/Dockerfile index 1b84855c..dbf8a3a9 100644 --- a/services/unbound/Dockerfile +++ b/services/unbound/Dockerfile @@ -1,7 +1,12 @@ -FROM python:3-alpine - +FROM alpine:3.8 +# python3 shared with most images +RUN apk add --no-cache \ + python3 py3-pip \ + && pip3 install --upgrade pip +# Shared layer between rspamd, postfix, dovecot, unbound and nginx +RUN pip3 install jinja2 +# Image specific layers under this line RUN apk add --no-cache unbound curl bind-tools \ - && pip3 install jinja2 \ && curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.cache \ && chown root:unbound /etc/unbound \ && chmod 775 /etc/unbound \ diff --git a/services/unbound/start.py b/services/unbound/start.py index 82e017f7..6f494762 100755 --- a/services/unbound/start.py +++ b/services/unbound/start.py @@ -1,4 +1,4 @@ -#!/usr/local/bin/python3 +#!/usr/bin/python3 import jinja2 import os diff --git a/webmails/rainloop/Dockerfile b/webmails/rainloop/Dockerfile index 5d751716..db7403f5 100644 --- a/webmails/rainloop/Dockerfile +++ b/webmails/rainloop/Dockerfile @@ -1,9 +1,13 @@ FROM php:7.2-apache +#Shared layer between rainloop and roundcube +RUN apt-get update && apt-get install -y \ + python3 curl \ + && rm -rf /var/lib/apt/lists 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 curl \ + unzip python3-jinja2 \ && rm -rf /var/www/html/ \ && mkdir /var/www/html \ && cd /var/www/html \ diff --git a/webmails/roundcube/Dockerfile b/webmails/roundcube/Dockerfile index 69e0f334..14bee56e 100644 --- a/webmails/roundcube/Dockerfile +++ b/webmails/roundcube/Dockerfile @@ -1,9 +1,13 @@ FROM php:7.2-apache +#Shared layer between rainloop and roundcube +RUN apt-get update && apt-get install -y \ + python3 curl \ + && rm -rf /var/lib/apt/lists ENV ROUNDCUBE_URL https://github.com/roundcube/roundcubemail/releases/download/1.3.8/roundcubemail-1.3.8-complete.tar.gz RUN apt-get update && apt-get install -y \ - zlib1g-dev curl \ + zlib1g-dev \ && docker-php-ext-install zip \ && echo date.timezone=UTC > /usr/local/etc/php/conf.d/timezone.ini \ && rm -rf /var/www/html/ \ @@ -19,14 +23,12 @@ RUN apt-get update && apt-get install -y \ && rm -rf /var/lib/apt/lists COPY php.ini /usr/local/etc/php/conf.d/roundcube.ini - COPY config.inc.php /var/www/html/config/ - -COPY start.sh /start.sh +COPY start.py /start.py EXPOSE 80/tcp VOLUME ["/data"] -CMD ["/start.sh"] +CMD /start.py HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 diff --git a/webmails/roundcube/start.py b/webmails/roundcube/start.py new file mode 100755 index 00000000..07b3a567 --- /dev/null +++ b/webmails/roundcube/start.py @@ -0,0 +1,10 @@ +#!/usr/bin/python3 + +import os + +# Fix some permissions +os.system("mkdir -p /data/gpg") +os.system("chown -R www-data:www-data /data") + +# Run apache +os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"]) \ No newline at end of file diff --git a/webmails/roundcube/start.sh b/webmails/roundcube/start.sh deleted file mode 100755 index 3fbc1fd4..00000000 --- a/webmails/roundcube/start.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -# Fix some permissions -mkdir -p /data/gpg -chown -R www-data:www-data /data - -# Run apache -exec apache2-foreground