From 9fe452e3d1d868b076a34888659ea701e136d192 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Tue, 27 Sep 2022 22:09:07 +0200 Subject: [PATCH] Use base image when building core images --- core/admin/Dockerfile | 53 ++++++++++------------------------------- core/dovecot/Dockerfile | 34 ++++++++------------------ core/nginx/Dockerfile | 43 ++++++++++++++++----------------- core/none/Dockerfile | 14 ++++++++--- core/postfix/Dockerfile | 41 ++++++++++--------------------- core/rspamd/Dockerfile | 29 ++++++++-------------- tests/build.hcl | 34 +++++++++++++++++++++++++- 7 files changed, 111 insertions(+), 137 deletions(-) diff --git a/core/admin/Dockerfile b/core/admin/Dockerfile index e4d870e0..c3731fb2 100644 --- a/core/admin/Dockerfile +++ b/core/admin/Dockerfile @@ -1,61 +1,34 @@ -# First stage to build assets -ARG DISTRO=alpine:3.14.5 +# syntax=docker/dockerfile-upstream:1.4.3 -FROM node:16-alpine3.16 as assets - -COPY package.json ./ -RUN set -eu \ - && npm config set update-notifier false \ - && npm install --no-fund - -COPY webpack.config.js ./ -COPY assets ./assets -RUN set -eu \ - && sed -i 's/#007bff/#55a5d9/' node_modules/admin-lte/build/scss/_bootstrap-variables.scss \ - && for l in ca da de:de-DE en:en-GB es:es-ES eu fr:fr-FR he hu is it:it-IT ja nb_NO:no-NB nl:nl-NL pl pt:pt-PT ru sv:sv-SE zh; do \ - cp node_modules/datatables.net-plugins/i18n/${l#*:}.json assets/${l%:*}.json; \ - done \ - && node_modules/.bin/webpack-cli --color - - -# Actual application -FROM $DISTRO -ARG VERSION - -ENV TZ Etc/UTC +FROM base +ARG VERSION=local LABEL version=$VERSION -# python3 shared with most images -RUN set -eu \ - && apk add --no-cache python3 py3-pip py3-wheel git bash tzdata \ - && pip3 install --upgrade pip - -RUN mkdir -p /app -WORKDIR /app - COPY requirements-prod.txt requirements.txt -RUN set -eu \ +RUN set -euxo pipefail \ && apk add --no-cache libressl curl postgresql-libs mariadb-connector-c \ && pip install --no-cache-dir -r requirements.txt --only-binary=:all: --no-binary=Flask-bootstrap,PyYAML,SQLAlchemy \ || ( apk add --no-cache --virtual build-dep libressl-dev libffi-dev python3-dev build-base postgresql-dev mariadb-connector-c-dev cargo \ - && pip install --upgrade pip \ && pip install -r requirements.txt \ && apk del --no-cache build-dep ) -COPY --from=assets static ./mailu/static COPY mailu ./mailu +RUN pybabel compile -d mailu/translations + COPY migrations ./migrations + COPY start.py /start.py COPY audit.py /audit.py -RUN pybabel compile -d mailu/translations +COPY --from=assets static ./mailu/static + +RUN echo $VERSION >> /version EXPOSE 80/tcp +HEALTHCHECK CMD curl -skfLo /dev/null http://localhost/sso/login?next=ui.index + VOLUME ["/data","/dkim"] + ENV FLASK_APP mailu - CMD /start.py - -HEALTHCHECK CMD curl -f -L http://localhost/sso/login?next=ui.index || exit 1 -RUN echo $VERSION >> /version diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index e44b69f7..2d74e59b 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -1,36 +1,22 @@ -ARG DISTRO=alpine:3.14.5 +# syntax=docker/dockerfile-upstream:1.4.3 + +FROM base -FROM $DISTRO ARG VERSION -ENV TZ Etc/UTC - LABEL version=$VERSION -# python3 shared with most images -RUN apk add --no-cache \ - python3 py3-pip git bash py3-multidict py3-yarl tzdata \ - && pip3 install --upgrade pip - -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube -RUN pip3 install socrate==0.2.0 - -# Shared layer between dovecot and postfix -RUN apk add --no-cache --virtual .build-deps gcc musl-dev python3-dev \ - && pip3 install "podop>0.2.5" \ - && apk del .build-deps - -# Image specific layers under this line -RUN apk add --no-cache \ - dovecot dovecot-lmtpd dovecot-pop3d dovecot-submissiond dovecot-pigeonhole-plugin rspamd-client xapian-core dovecot-fts-xapian \ - && mkdir /var/lib/dovecot +RUN set -euxo pipefail \ + && apk add --no-cache dovecot dovecot-lmtpd dovecot-pop3d dovecot-submissiond dovecot-pigeonhole-plugin rspamd-client xapian-core dovecot-fts-xapian \ + && mkdir /var/lib/dovecot COPY conf /conf COPY start.py /start.py +RUN echo $VERSION >> /version + EXPOSE 110/tcp 143/tcp 993/tcp 4190/tcp 2525/tcp +HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 110|grep "Dovecot ready." + VOLUME ["/mail"] CMD /start.py - -HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 110|grep "Dovecot ready." -RUN echo $VERSION >> /version \ No newline at end of file diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 07021429..2a34403f 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -1,34 +1,33 @@ -ARG DISTRO=alpine:3.14.5 -FROM $DISTRO +# syntax=docker/dockerfile-upstream:1.4.3 + +FROM base as static + +COPY static /static + +RUN set -euxo pipefail \ + && gzip -k9 /static/*.ico /static/*.txt \ + && chmod a+rX-w -R /static + + +FROM base + ARG VERSION - -ENV TZ Etc/UTC - LABEL version=$VERSION -# python3 shared with most images -RUN apk add --no-cache \ - python3 py3-pip git bash py3-multidict \ - && pip3 install --upgrade pip - -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube -RUN pip3 install socrate==0.2.0 - # Image specific layers under this line -RUN apk add --no-cache certbot nginx nginx-mod-mail openssl curl tzdata \ - && pip3 install watchdog +RUN set -euxo pipefail \ + && apk add --no-cache certbot nginx nginx-mod-mail openssl curl \ + && pip3 install --no-cache-dir watchdog COPY conf /conf -COPY static /static +COPY --from=static /static /static COPY *.py / -RUN gzip -k9 /static/*.ico /static/*.txt; chmod a+rX -R /static +RUN echo $VERSION >> /version EXPOSE 80/tcp 443/tcp 110/tcp 143/tcp 465/tcp 587/tcp 993/tcp 995/tcp 25/tcp 10025/tcp 10143/tcp -VOLUME ["/certs"] -VOLUME ["/overrides"] +HEALTHCHECK --start-period=60s CMD curl -skfLo /dev/null http://localhost/health + +VOLUME ["/certs", "/overrides"] CMD /start.py - -HEALTHCHECK CMD curl -k -f -L http://localhost/health || exit 1 -RUN echo $VERSION >> /version \ No newline at end of file diff --git a/core/none/Dockerfile b/core/none/Dockerfile index 06d351a9..058b18c5 100644 --- a/core/none/Dockerfile +++ b/core/none/Dockerfile @@ -1,6 +1,14 @@ +# syntax=docker/dockerfile-upstream:1.4.3 # This is an idle image to dynamically replace any component if disabled. -ARG DISTRO=alpine:3.14.5 -FROM $DISTRO +FROM base -CMD sleep 1000000d +ARG VERSION=local +LABEL version=$VERSION + +RUN echo $VERSION >> /version + +HEALTHCHECK CMD true + +USER app +CMD ["/bin/bash", "-c", "sleep infinity"] diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index 373e5c8d..66adbde3 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -1,40 +1,25 @@ -ARG DISTRO=alpine:3.14.5 +# syntax=docker/dockerfile-upstream:1.4.3 -FROM $DISTRO -ARG VERSION - -ENV TZ Etc/UTC +FROM base +ARG VERSION=local LABEL version=$VERSION -# python3 shared with most images -RUN apk add --no-cache \ - python3 py3-pip git bash py3-multidict py3-yarl tzdata \ - && pip3 install --upgrade pip - -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube -RUN pip3 install socrate==0.2.0 - -# Shared layer between dovecot and postfix -RUN apk add --no-cache --virtual .build-deps gcc musl-dev python3-dev \ - && pip3 install "podop>0.2.5" \ - && apk del .build-deps - -# Image specific layers under this line -# Building pycares from source requires py3-wheel and libffi-dev packages -RUN pip install --no-cache-dir --only-binary=:all: postfix-mta-sts-resolver==1.0.1 || (apk add --no-cache --virtual .build-deps gcc musl-dev python3-dev py3-wheel libffi-dev \ - && pip3 install postfix-mta-sts-resolver==1.0.1 \ - && apk del .build-deps ) - -RUN apk add --no-cache postfix postfix-pcre cyrus-sasl-login rsyslog logrotate +RUN set -euxo pipefail \ + && apk add --no-cache postfix postfix-pcre cyrus-sasl-login rsyslog logrotate \ + && pip install --no-cache-dir --only-binary=:all: postfix-mta-sts-resolver==1.0.1 \ + || ( apk add --no-cache --virtual .build-deps gcc musl-dev python3-dev py3-wheel libffi-dev \ + && pip3 install postfix-mta-sts-resolver==1.0.1 \ + && apk del .build-deps ) COPY conf /conf COPY start.py /start.py +RUN echo $VERSION >> /version + EXPOSE 25/tcp 10025/tcp +HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 25|grep "220 .* ESMTP Postfix" + VOLUME ["/queue"] CMD /start.py - -HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 25|grep "220 .* ESMTP Postfix" -RUN echo $VERSION >> /version diff --git a/core/rspamd/Dockerfile b/core/rspamd/Dockerfile index 7b89aed0..5ee922e5 100644 --- a/core/rspamd/Dockerfile +++ b/core/rspamd/Dockerfile @@ -1,31 +1,22 @@ -ARG DISTRO=alpine:3.15 -FROM $DISTRO -ARG VERSION -ENV TZ Etc/UTC +# syntax=docker/dockerfile-upstream:1.4.3 +FROM base + +ARG VERSION=local LABEL version=$VERSION -# python3 shared with most images -RUN apk add --no-cache \ - python3 py3-pip git bash py3-multidict tzdata \ - && pip3 install --upgrade pip - -# Shared layer between nginx, dovecot, postfix, postgresql, rspamd, unbound, snappymail, roundcube -RUN pip3 install socrate==0.2.0 - -# 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 +RUN set -euxo pipefail \ + && apk add --no-cache rspamd rspamd-controller rspamd-proxy rspamd-fuzzy ca-certificates curl \ + && mkdir /run/rspamd COPY conf/ /conf COPY start.py /start.py +RUN echo $VERSION >> /version + EXPOSE 11332/tcp 11334/tcp 11335/tcp +HEALTHCHECK --start-period=350s CMD curl -skfLo /dev/null http://localhost:11334/ VOLUME ["/var/lib/rspamd"] CMD /start.py - -HEALTHCHECK --start-period=350s CMD curl -f -L http://localhost:11334/ || exit 1 -RUN echo $VERSION >> /version \ No newline at end of file diff --git a/tests/build.hcl b/tests/build.hcl index 3df00b51..c32da8d5 100644 --- a/tests/build.hcl +++ b/tests/build.hcl @@ -78,6 +78,19 @@ function "tag" { # docker buildx bake -f tests\build.hcl docs #----------------------------------------------------------------------------------------- +# ----------------------------------------------------------------------------------------- +# Base images +# ----------------------------------------------------------------------------------------- +target "base" { + inherits = ["defaults"] + context="core/base" +} + +target "assets" { + inherits = ["defaults"] + context="core/admin/assets" +} + # ----------------------------------------------------------------------------------------- # Documentation and setup images # ----------------------------------------------------------------------------------------- @@ -103,36 +116,55 @@ target "setup" { target "none" { inherits = ["defaults"] context="core/none" + contexts= { + base = "target:base" + } tags = tag("none") } target "admin" { inherits = ["defaults"] context="core/admin" + contexts= { + base = "target:base" + assets = "target:assets" + } tags = tag("admin") } target "antispam" { inherits = ["defaults"] context="core/rspamd" + contexts= { + base = "target:base" + } tags = tag("rspamd") } target "front" { inherits = ["defaults"] context="core/nginx" + contexts= { + base = "target:base" + } tags = tag("nginx") } target "imap" { inherits = ["defaults"] context="core/dovecot" + contexts= { + base = "target:base" + } tags = tag("dovecot") } target "smtp" { inherits = ["defaults"] context="core/postfix" + contexts= { + base = "target:base" + } tags = tag("postfix") } @@ -182,4 +214,4 @@ target "webdav" { inherits = ["defaults"] context="optional/radicale" tags = tag("radicale") -} \ No newline at end of file +}