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 1/8] 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 2/8] 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 3/8] 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 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 4/8] 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 5/8] 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 6/8] 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 c3e89967fb8ce7fc1fd431a2e618b82cc856cb4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 21 Oct 2018 20:45:41 +0300 Subject: [PATCH 7/8] Fix front health checking - Specified seperated /health path in order to allow for healthcheck even if webmail and admin are not seletectd. This also allows healthchecking fom external services like DNS load balancers; - Make curl not to fail on TLS because localhost is not included in the certificates. --- core/nginx/Dockerfile | 2 +- core/nginx/conf/nginx.conf | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/core/nginx/Dockerfile b/core/nginx/Dockerfile index 87951c03..00ecf84e 100644 --- a/core/nginx/Dockerfile +++ b/core/nginx/Dockerfile @@ -13,4 +13,4 @@ VOLUME ["/certs"] CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost/ || exit 1 +HEALTHCHECK CMD curl -k -f -L http://localhost/health || exit 1 diff --git a/core/nginx/conf/nginx.conf b/core/nginx/conf/nginx.conf index 8fcda1c3..d2cbc7fe 100644 --- a/core/nginx/conf/nginx.conf +++ b/core/nginx/conf/nginx.conf @@ -146,6 +146,10 @@ http { proxy_pass_request_body off; proxy_set_header Content-Length ""; } + + location /health { + return 204; + } } # Forwarding authentication server From a2fea36c79367ce967e4b96a028aa5ff86c869dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sun, 21 Oct 2018 20:49:01 +0300 Subject: [PATCH 8/8] Increase HEALTHCHECK start time for services that need to wait for host resolving during startup. In Docker Swarm mode the services listed below can get stuck in their start script, while they are waiting for other services become available. Now, with HEALTHCHECK enabled, docker does not resolve names of services that not pass HEALTHCHECK yet. Meaning that if one of the depenend services is not yet available, it will create a chain of failing services. The services below retry to resolve 100 time, with an average of 3.5 seconds. Hence, the --start-time flag is now set at 350 seconds. - dovecot (imap) - postfix (smtp) - rspamd (antispam) --- core/dovecot/Dockerfile | 2 +- core/postfix/Dockerfile | 2 +- services/rspamd/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/dovecot/Dockerfile b/core/dovecot/Dockerfile index c0d3e3cd..e19631ee 100644 --- a/core/dovecot/Dockerfile +++ b/core/dovecot/Dockerfile @@ -14,4 +14,4 @@ VOLUME ["/data", "/mail"] CMD /start.py -HEALTHCHECK CMD echo QUIT|nc localhost 110|grep "Dovecot ready." +HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 110|grep "Dovecot ready." diff --git a/core/postfix/Dockerfile b/core/postfix/Dockerfile index 5533499e..e0529e01 100644 --- a/core/postfix/Dockerfile +++ b/core/postfix/Dockerfile @@ -13,4 +13,4 @@ VOLUME ["/data"] CMD /start.py -HEALTHCHECK CMD echo QUIT|nc localhost 25|grep "220 .* ESMTP Postfix" +HEALTHCHECK --start-period=350s CMD echo QUIT|nc localhost 25|grep "220 .* ESMTP Postfix" diff --git a/services/rspamd/Dockerfile b/services/rspamd/Dockerfile index d87a64f5..4337fb2e 100644 --- a/services/rspamd/Dockerfile +++ b/services/rspamd/Dockerfile @@ -18,4 +18,4 @@ VOLUME ["/var/lib/rspamd"] CMD /start.py -HEALTHCHECK CMD curl -f -L http://localhost:11334/ || exit 1 +HEALTHCHECK --start-period=350s CMD curl -f -L http://localhost:11334/ || exit 1