mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
Enhancement: Add Docker Hub image (#965)
* Enhancement: Add Docker Hub image * Push to ghcr.io * Add all `org.opencontainers.image.xxx` labels using `--label` instead of `LABEL` * Change `php-fpm` to listen on `:9000` to expose prometheus metrics via `php-fpm_exporter` * Include `yarn.lock` to speed up builds * Reorder * Use correct sha for pr * Add logging before overriding values in config * Add `DEBUG=true` env var for verbose `entrypoint.sh` logs * Print php exception when snappymail fails to generate data directory and config file on the very first time * Log snappymail version * Fix COPY statement * Add .dockerignore * Add `USER` and `ENTRYPOINT` * Update `.dockerignore` * Add docker image test * Push only if image test succeeds * Log when startup is successful * Use plain `docker build` in `build_and_test.sh` * Fix test output
This commit is contained in:
parent
6552a93989
commit
24dbff999e
|
@ -1,51 +1,116 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
FROM alpine:3.15 AS builder
|
||||||
|
RUN apk add --no-cache php7 php7-json php-phar php-zip
|
||||||
|
RUN apk add --no-cache npm
|
||||||
|
RUN npm install -g gulp yarn
|
||||||
|
WORKDIR /source
|
||||||
|
COPY package.json yarn.lock ./
|
||||||
|
RUN yarn install
|
||||||
|
COPY . .
|
||||||
|
# Patch release.php with hotfix from: https://github.com/xgbstar1/snappymail-docker/blob/main/Dockerfile, so that release.php doesn't fail with error
|
||||||
|
RUN sed -i 's_^if.*rename.*snappymail.v.0.0.0.*$_if (!!system("mv snappymail/v/0.0.0 snappymail/v/{$package->version}")) {_' cli/release.php || true
|
||||||
|
RUN php release.php
|
||||||
|
RUN set -eux; \
|
||||||
|
VERSION=$( ls build/dist/releases/webmail ); \
|
||||||
|
ls -al build/dist/releases/webmail/$VERSION/snappymail-$VERSION.tar.gz; \
|
||||||
|
mkdir -p /snappymail; \
|
||||||
|
tar -zxvf build/dist/releases/webmail/$VERSION/snappymail-$VERSION.tar.gz -C /snappymail; \
|
||||||
|
find /snappymail -type d -exec chmod 550 {} \; ; \
|
||||||
|
find /snappymail -type f -exec chmod 440 {} \; ; \
|
||||||
|
find /snappymail/data -type d -exec chmod 750 {} \; ; \
|
||||||
|
# Remove unneeded files
|
||||||
|
rm -v /snappymail/README.md /snappymail/_include.php
|
||||||
|
|
||||||
# Inspired by the original Rainloop dockerfile from youtous on GitLab
|
# Inspired by the original Rainloop dockerfile from youtous on GitLab
|
||||||
FROM php:8.1-fpm-bullseye
|
FROM php:8.1-fpm-alpine AS final
|
||||||
|
|
||||||
ARG FILES_ZIP
|
LABEL org.label-schema.description="SnappyMail webmail client image using nginx, php-fpm on Alpine"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LABEL org.label-schema.description="SnappyMail webmail client image using nginx, php-fpm based on Debian Buster"
|
|
||||||
|
|
||||||
ENV UID=991 GID=991 UPLOAD_MAX_SIZE=25M LOG_TO_STDERR=true MEMORY_LIMIT=128M SECURE_COOKIES=true
|
|
||||||
ENV fpm.pool.clear_env=false
|
|
||||||
|
|
||||||
# Install dependencies such as nginx
|
# Install dependencies such as nginx
|
||||||
RUN mkdir -p /usr/share/man/man1/ /usr/share/man/man3/ /usr/share/man/man7/ && \
|
RUN apk add --no-cache ca-certificates nginx supervisor bash
|
||||||
apt-get update -q --fix-missing && \
|
|
||||||
apt-get -y upgrade && \
|
|
||||||
apt-get install --no-install-recommends -y \
|
|
||||||
apt-transport-https gnupg openssl wget curl ca-certificates nginx supervisor sudo \
|
|
||||||
unzip libzip-dev libxml2-dev libldb-dev libldap2-dev \
|
|
||||||
sqlite3 libsqlite3-dev libsqlite3-0 libpq-dev postgresql-client mariadb-client logrotate \
|
|
||||||
zip mlocate libpcre3-dev libicu-dev \
|
|
||||||
build-essential chrpath libssl-dev \
|
|
||||||
libxft-dev libfreetype6 libfreetype6-dev \
|
|
||||||
libpng-dev libjpeg62-turbo-dev \
|
|
||||||
libfontconfig1 libfontconfig1-dev \
|
|
||||||
&& \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Install PHP extensions
|
# Install PHP extensions
|
||||||
RUN php -m && \
|
# gd
|
||||||
docker-php-ext-configure ldap --with-libdir=lib/$(uname -m)-linux-gnu/ && \
|
RUN set -eux; \
|
||||||
docker-php-ext-configure intl && \
|
apk add --no-cache freetype libjpeg-turbo libpng; \
|
||||||
docker-php-ext-configure gd --with-freetype --with-jpeg && \
|
apk add --no-cache --virtual .deps freetype-dev libjpeg-turbo-dev libpng-dev; \
|
||||||
docker-php-ext-install ldap opcache pdo_mysql pdo_pgsql zip intl gd && \
|
docker-php-ext-configure gd --with-freetype --with-jpeg; \
|
||||||
php -m
|
docker-php-ext-install gd; \
|
||||||
|
apk del .deps
|
||||||
|
# gnupg
|
||||||
|
RUN set -eux; \
|
||||||
|
apk add --no-cache gnupg gpgme; \
|
||||||
|
apk add --no-cache --virtual .deps gpgme-dev; \
|
||||||
|
apk add --no-cache --virtual .build-dependencies $PHPIZE_DEPS; \
|
||||||
|
pecl install gnupg; \
|
||||||
|
docker-php-ext-enable gnupg; \
|
||||||
|
docker-php-source delete; \
|
||||||
|
apk del .build-dependencies; \
|
||||||
|
apk del .deps
|
||||||
|
# intl
|
||||||
|
RUN set -eux; \
|
||||||
|
apk add --no-cache icu-libs; \
|
||||||
|
apk add --no-cache --virtual .deps icu-dev; \
|
||||||
|
docker-php-ext-configure intl; \
|
||||||
|
docker-php-ext-install intl; \
|
||||||
|
apk del .deps
|
||||||
|
# ldap
|
||||||
|
RUN set -eux; \
|
||||||
|
apk add --no-cache libldap; \
|
||||||
|
apk add --no-cache --virtual .deps openldap-dev; \
|
||||||
|
docker-php-ext-configure ldap; \
|
||||||
|
docker-php-ext-install ldap; \
|
||||||
|
apk del .deps
|
||||||
|
# mysql
|
||||||
|
RUN docker-php-ext-install pdo_mysql
|
||||||
|
# opcache
|
||||||
|
RUN docker-php-ext-install opcache
|
||||||
|
# postgres
|
||||||
|
RUN set -eux; \
|
||||||
|
apk add --no-cache postgresql-libs; \
|
||||||
|
apk add --no-cache --virtual .deps postgresql-dev; \
|
||||||
|
docker-php-ext-install pdo_pgsql; \
|
||||||
|
apk del .deps
|
||||||
|
# redis
|
||||||
|
RUN set -eux; \
|
||||||
|
apk add --no-cache liblzf zstd-libs; \
|
||||||
|
apk add --no-cache --virtual .deps zstd-dev; \
|
||||||
|
apk add --no-cache --virtual .build-dependencies $PHPIZE_DEPS; \
|
||||||
|
pecl install igbinary; \
|
||||||
|
docker-php-ext-enable igbinary; \
|
||||||
|
pecl install --configureoptions 'enable-redis-igbinary="yes" enable-redis-lzf="yes" enable-redis-zstd="yes"' redis; \
|
||||||
|
docker-php-ext-enable redis; \
|
||||||
|
docker-php-source delete; \
|
||||||
|
apk del .build-dependencies; \
|
||||||
|
apk del .deps
|
||||||
|
# zip
|
||||||
|
RUN set -eux; \
|
||||||
|
apk add --no-cache libzip; \
|
||||||
|
apk add --no-cache --virtual .deps libzip-dev; \
|
||||||
|
docker-php-ext-install zip; \
|
||||||
|
apk del .deps
|
||||||
|
|
||||||
# Install snappymail
|
# Install snappymail
|
||||||
WORKDIR /tmp
|
# The 'www-data' user/group in alpine is 82:82. The 'nginx' user/group in alpine is 101:101, and is part of www-data group
|
||||||
COPY ${FILES_ZIP} .
|
COPY --chown=www-data:www-data --from=builder /snappymail /snappymail
|
||||||
RUN mkdir /snappymail && \
|
# Use a custom snappymail data folder
|
||||||
unzip -q ${FILES_ZIP} -d /snappymail && \
|
RUN mv -v /snappymail/data /var/lib/snappymail;
|
||||||
find /snappymail -type d -exec chmod 755 {} \; && \
|
# Setup configs
|
||||||
find /snappymail -type f -exec chmod 644 {} \; && \
|
COPY --chown=root:root .docker/release/files /
|
||||||
rm -rf ${FILES_ZIP}
|
RUN set -eux; \
|
||||||
|
chown www-data:www-data /snappymail/include.php; \
|
||||||
|
chmod 440 /snappymail/include.php; \
|
||||||
|
chmod +x /entrypoint.sh; \
|
||||||
|
# Disable the built-in php-fpm configs, since we're using our own config
|
||||||
|
mv -v /usr/local/etc/php-fpm.d/docker.conf /usr/local/etc/php-fpm.d/docker.conf.disabled; \
|
||||||
|
mv -v /usr/local/etc/php-fpm.d/www.conf /usr/local/etc/php-fpm.d/www.conf.disabled; \
|
||||||
|
mv -v /usr/local/etc/php-fpm.d/zz-docker.conf /usr/local/etc/php-fpm.d/zz-docker.conf.disabled;
|
||||||
|
|
||||||
# Install other content
|
USER root
|
||||||
COPY files /
|
WORKDIR /snappymail
|
||||||
RUN chmod +x /entrypoint.sh && chmod +x /logrotate-loop.sh
|
VOLUME /var/lib/snappymail
|
||||||
VOLUME /snappymail/data
|
|
||||||
EXPOSE 8888
|
EXPOSE 8888
|
||||||
|
EXPOSE 9000
|
||||||
|
ENTRYPOINT []
|
||||||
CMD ["/entrypoint.sh"]
|
CMD ["/entrypoint.sh"]
|
||||||
|
|
92
.docker/release/files/entrypoint.sh
Normal file → Executable file
92
.docker/release/files/entrypoint.sh
Normal file → Executable file
|
@ -1,23 +1,20 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
# Create not root user
|
DEBUG=${DEBUG:-}
|
||||||
groupadd --gid "$GID" php-cli -f
|
if [ "$DEBUG" = 'true' ]; then
|
||||||
adduser --uid "$UID" --disabled-password --gid "$GID" --shell /bin/bash --home /home/php-cli php-cli --force --gecos ""
|
set -x
|
||||||
|
fi
|
||||||
|
UPLOAD_MAX_SIZE=${UPLOAD_MAX_SIZE:-25M}
|
||||||
|
MEMORY_LIMIT=${MEMORY_LIMIT:-128M}
|
||||||
|
SECURE_COOKIES=${SECURE_COOKIES:-true}
|
||||||
|
|
||||||
# Set attachment size limit
|
# Set attachment size limit
|
||||||
sed -i "s/<UPLOAD_MAX_SIZE>/$UPLOAD_MAX_SIZE/g" /usr/local/etc/php-fpm.d/php-fpm.conf /etc/nginx/nginx.conf
|
sed -i "s/<UPLOAD_MAX_SIZE>/$UPLOAD_MAX_SIZE/g" /usr/local/etc/php-fpm.d/php-fpm.conf /etc/nginx/nginx.conf
|
||||||
sed -i "s/<MEMORY_LIMIT>/$MEMORY_LIMIT/g" /usr/local/etc/php-fpm.d/php-fpm.conf
|
sed -i "s/<MEMORY_LIMIT>/$MEMORY_LIMIT/g" /usr/local/etc/php-fpm.d/php-fpm.conf
|
||||||
|
|
||||||
# Set log output to STDERR if wanted (LOG_TO_STDERR=true)
|
|
||||||
if [ "$LOG_TO_STDERR" = true ]; then
|
|
||||||
echo "[INFO] Logging to stderr activated"
|
|
||||||
sed -i "s/.*error_log.*$/error_log \/dev\/stderr warn;/" /etc/nginx/nginx.conf
|
|
||||||
sed -i "s/.*error_log.*$/php_admin_value[error_log] = \/dev\/stderr/" /usr/local/etc/php-fpm.d/php-fpm.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Secure cookies
|
# Secure cookies
|
||||||
if [ "${SECURE_COOKIES}" = true ]; then
|
if [ "${SECURE_COOKIES}" = 'true' ]; then
|
||||||
echo "[INFO] Secure cookies activated"
|
echo "[INFO] Secure cookies activated"
|
||||||
{
|
{
|
||||||
echo 'session.cookie_httponly = On';
|
echo 'session.cookie_httponly = On';
|
||||||
|
@ -26,43 +23,58 @@ if [ "${SECURE_COOKIES}" = true ]; then
|
||||||
} > /usr/local/etc/php/conf.d/cookies.ini;
|
} > /usr/local/etc/php/conf.d/cookies.ini;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Copy snappymail default config if absent
|
echo "[INFO] Snappymail version: $( ls /snappymail/snappymail/v )"
|
||||||
SNAPPYMAIL_CONFIG_FILE=/snappymail/data/_data_/_default_/configs/application.ini
|
|
||||||
|
# Set permissions on snappymail data
|
||||||
|
echo "[INFO] Setting permissions on /var/lib/snappymail"
|
||||||
|
chown -R www-data:www-data /var/lib/snappymail/
|
||||||
|
chmod 550 /var/lib/snappymail/
|
||||||
|
find /var/lib/snappymail/ -type d -exec chmod 750 {} \;
|
||||||
|
|
||||||
|
# Create snappymail default config if absent
|
||||||
|
SNAPPYMAIL_CONFIG_FILE=/var/lib/snappymail/_data_/_default_/configs/application.ini
|
||||||
if [ ! -f "$SNAPPYMAIL_CONFIG_FILE" ]; then
|
if [ ! -f "$SNAPPYMAIL_CONFIG_FILE" ]; then
|
||||||
echo "[INFO] Creating default Snappymail configuration"
|
echo "[INFO] Creating default Snappymail configuration: $SNAPPYMAIL_CONFIG_FILE"
|
||||||
mkdir -p $(dirname $SNAPPYMAIL_CONFIG_FILE)
|
# Run snappymail and exit. This populates the snappymail data directory and generates the config file
|
||||||
cp /usr/local/include/application.ini $SNAPPYMAIL_CONFIG_FILE
|
# On error, print php exception and exit
|
||||||
|
EXITCODE=
|
||||||
|
su - www-data -s /bin/sh -c 'php /snappymail/index.php' > /tmp/out || EXITCODE=$?
|
||||||
|
if [ -n "$EXITCODE" ]; then
|
||||||
|
cat /tmp/out
|
||||||
|
exit "$EXITCODE"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "[INFO] Overriding values in snappymail configuration: $SNAPPYMAIL_CONFIG_FILE"
|
||||||
# Enable output of snappymail logs
|
# Enable output of snappymail logs
|
||||||
if [ "${LOG_TO_STDERR}" = true ]; then
|
sed '/^\; Enable logging/{
|
||||||
sed -z 's/\; Enable logging\nenable = Off/\; Enable logging\nenable = On/' -i $SNAPPYMAIL_CONFIG_FILE
|
N
|
||||||
sed 's/^filename = .*/filename = "errors.log"/' -i $SNAPPYMAIL_CONFIG_FILE
|
s/enable = Off/enable = On/
|
||||||
sed 's/^write_on_error_only = .*/write_on_error_only = Off/' -i $SNAPPYMAIL_CONFIG_FILE
|
}' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
sed 's/^write_on_php_error_only = .*/write_on_php_error_only = On/' -i $SNAPPYMAIL_CONFIG_FILE
|
# Redirect snappymail logs to stderr /stdout
|
||||||
else
|
sed 's/^filename = .*/filename = "stderr"/' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
sed -z 's/\; Enable logging\nenable = On/\; Enable logging\nenable = Off/' -i $SNAPPYMAIL_CONFIG_FILE
|
sed 's/^write_on_error_only = .*/write_on_error_only = Off/' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
fi
|
sed 's/^write_on_php_error_only = .*/write_on_php_error_only = On/' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
# Always enable snappymail Auth logging
|
# Always enable snappymail Auth logging
|
||||||
sed 's/^auth_logging = .*/auth_logging = On/' -i $SNAPPYMAIL_CONFIG_FILE
|
sed 's/^auth_logging = .*/auth_logging = On/' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
sed 's/^auth_logging_filename = .*/auth_logging_filename = "auth.log"/' -i $SNAPPYMAIL_CONFIG_FILE
|
sed 's/^auth_logging_filename = .*/auth_logging_filename = "auth.log"/' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
sed 's/^auth_logging_format = .*/auth_logging_format = "[{date:Y-m-d H:i:s}] Auth failed: ip={request:ip} user={imap:login} host={imap:host} port={imap:port}"/' -i $SNAPPYMAIL_CONFIG_FILE
|
sed 's/^auth_logging_format = .*/auth_logging_format = "[{date:Y-m-d H:i:s}] Auth failed: ip={request:ip} user={imap:login} host={imap:host} port={imap:port}"/' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
# Redirect snappymail logs to stderr /stdout
|
sed 's/^auth_syslog = .*/auth_syslog = Off/' -i $SNAPPYMAIL_CONFIG_FILE
|
||||||
mkdir -p /snappymail/data/_data_/_default_/logs/
|
|
||||||
# empty logs
|
|
||||||
cp /dev/null /snappymail/data/_data_/_default_/logs/errors.log
|
|
||||||
cp /dev/null /snappymail/data/_data_/_default_/logs/auth.log
|
|
||||||
chown -R php-cli:php-cli /snappymail/data/
|
|
||||||
|
|
||||||
# Fix permissions
|
(
|
||||||
chown -R $UID:$GID /snappymail/data /var/log /var/lib/nginx
|
while ! nc -vz -w 1 localhost 8888 > /dev/null 2>&1; do echo "[INFO] Checking whether nginx is alive"; sleep 1; done
|
||||||
chmod o+w /dev/stdout
|
while ! nc -vz -w 1 localhost 9000 > /dev/null 2>&1; do echo "[INFO] Checking whether php-fpm is alive"; sleep 1; done
|
||||||
chmod o+w /dev/stderr
|
# Create snappymail admin password if absent
|
||||||
|
SNAPPYMAIL_ADMIN_PASSWORD_FILE=/var/lib/snappymail/_data_/_default_/admin_password.txt
|
||||||
|
if [ ! -f "$SNAPPYMAIL_ADMIN_PASSWORD_FILE" ]; then
|
||||||
|
echo "[INFO] Creating Snappymail admin password file: $SNAPPYMAIL_ADMIN_PASSWORD_FILE"
|
||||||
|
wget -T 1 -qO- 'http://localhost:8888/?/AdminAppData/0/12345/' > /dev/null
|
||||||
|
echo "[INFO] Snappymail Admin Panel ready at http://localhost:8888/?admin. Login using password in $SNAPPYMAIL_ADMIN_PASSWORD_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
wget -T 1 -qO- 'http://localhost:8888/' > /dev/null
|
||||||
# Touch supervisord PID file in order to fix permissions
|
echo "[INFO] Snappymail ready at http://localhost:8888/"
|
||||||
touch /run/supervisord.pid
|
) &
|
||||||
chown php-cli:php-cli /run/supervisord.pid
|
|
||||||
|
|
||||||
# RUN !
|
# RUN !
|
||||||
exec sudo -u php-cli -g php-cli /usr/bin/supervisord -c '/supervisor.conf' --pidfile '/run/supervisord.pid'
|
exec /usr/bin/supervisord -c /supervisor.conf --pidfile /run/supervisord.pid
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
/snappymail/data/_data_/_default_/logs/* {
|
|
||||||
size 10M
|
|
||||||
rotate 0
|
|
||||||
missingok
|
|
||||||
}
|
|
|
@ -11,7 +11,7 @@ http {
|
||||||
default_type application/octet-stream;
|
default_type application/octet-stream;
|
||||||
|
|
||||||
access_log off;
|
access_log off;
|
||||||
error_log /tmp/ngx_error.log error;
|
error_log /dev/stderr error;
|
||||||
|
|
||||||
sendfile on;
|
sendfile on;
|
||||||
keepalive_timeout 15;
|
keepalive_timeout 15;
|
||||||
|
@ -95,7 +95,7 @@ http {
|
||||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
fastcgi_param HTTP_PROXY "";
|
fastcgi_param HTTP_PROXY "";
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
fastcgi_pass unix:/tmp/php-fpm.sock;
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
fastcgi_intercept_errors on;
|
fastcgi_intercept_errors on;
|
||||||
fastcgi_request_buffering off;
|
fastcgi_request_buffering off;
|
||||||
fastcgi_param REMOTE_ADDR $http_x_real_ip;
|
fastcgi_param REMOTE_ADDR $http_x_real_ip;
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Simple script to invoke logrotate at regular intervals
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
# from https://github.com/misho-kr/docker-appliances/blob/master/nginx-nodejs/logrotate-loop.sh
|
|
||||||
|
|
||||||
LOGROTATE_BIN="logrotate"
|
|
||||||
|
|
||||||
STATE="$HOME/logrotate.state"
|
|
||||||
CONF="/etc/logrotate.d/snappymail"
|
|
||||||
|
|
||||||
export LOGROTATE_BIN STATE CONF
|
|
||||||
|
|
||||||
RUN_INTERVAL="3600" # every hour
|
|
||||||
|
|
||||||
# helper functions for logging
|
|
||||||
export FMT="%a %b %d %Y %H:%M:%S GMT%z (%Z)"
|
|
||||||
|
|
||||||
function log_date() {
|
|
||||||
echo "$(date +"$FMT"): $*"
|
|
||||||
}
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Main loop of the logrotate service:
|
|
||||||
#
|
|
||||||
# while True:
|
|
||||||
# sleep N seconds
|
|
||||||
# run logrotate
|
|
||||||
#
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
function logrotate_loop() {
|
|
||||||
|
|
||||||
trap on_terminate TERM INT
|
|
||||||
|
|
||||||
local interval="${1}"
|
|
||||||
|
|
||||||
log_date "===================================================="
|
|
||||||
log_date
|
|
||||||
log_date "logrotate service starting (pid=$$)"
|
|
||||||
log_date "logrotate process will run every ${interval} seconds"
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
|
|
||||||
current_time=$(date "+%s")
|
|
||||||
next_run_time=$(( current_time + interval ))
|
|
||||||
|
|
||||||
while (( current_time < next_run_time ))
|
|
||||||
do
|
|
||||||
logrotate_sleep $(( next_run_time - current_time ))
|
|
||||||
current_time=$(date "+%s")
|
|
||||||
done
|
|
||||||
|
|
||||||
logrotate_run
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# helper function to execute logrotate and pass it the right parameters
|
|
||||||
function logrotate_run() {
|
|
||||||
|
|
||||||
log_date "logrotate will run now"
|
|
||||||
${LOGROTATE_BIN} -s ${STATE} ${CONF}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Procedure to idle the execution for a number of seconds
|
|
||||||
#
|
|
||||||
# There are two requirements:
|
|
||||||
#
|
|
||||||
# - export the PID of the sleep command so that it can be terminated
|
|
||||||
# in case the logrotate service is being shutdown
|
|
||||||
# - keep this (bash) process responsive to SIGTERM while in sleep
|
|
||||||
# mode (normally the signal will be masked and will not be delivered
|
|
||||||
# until the subprocess completes)
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
proc_sleep_pid=""
|
|
||||||
|
|
||||||
function logrotate_sleep() {
|
|
||||||
|
|
||||||
local sleep_interval=${1}
|
|
||||||
|
|
||||||
log_date "logrotate will sleep for ${sleep_interval} seconds"
|
|
||||||
|
|
||||||
( exec -a "logrotate: sleep" sleep ${sleep_interval} )&
|
|
||||||
|
|
||||||
proc_sleep_pid=$!
|
|
||||||
wait ${proc_sleep_pid}
|
|
||||||
}
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# Signal handler for logrotate service to make sure the process exits:
|
|
||||||
#
|
|
||||||
# - properly by terminating the sleep process that is used to idle
|
|
||||||
# the service
|
|
||||||
# - gracefully by writing a message in the log
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
function on_terminate() {
|
|
||||||
|
|
||||||
log_date "logrotate will terminate"
|
|
||||||
log_date
|
|
||||||
|
|
||||||
kill -TERM ${proc_sleep_pid}
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
# main
|
|
||||||
# ----------------------------------------------------------------------
|
|
||||||
|
|
||||||
logrotate_loop ${1:-RUN_INTERVAL}
|
|
3
.docker/release/files/snappymail/include.php
Normal file
3
.docker/release/files/snappymail/include.php
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<?php
|
||||||
|
define('APP_DATA_FOLDER_PATH', '/var/lib/snappymail/');
|
||||||
|
?>
|
|
@ -1,10 +1,13 @@
|
||||||
[supervisord]
|
[supervisord]
|
||||||
nodaemon=true
|
nodaemon=true
|
||||||
|
user=root
|
||||||
|
logfile=/dev/null
|
||||||
|
logfile_maxbytes=0
|
||||||
|
|
||||||
[program:nginx]
|
[program:nginx]
|
||||||
command=nginx -c /etc/nginx/nginx.conf -g 'daemon off;'
|
command=nginx -c /etc/nginx/nginx.conf -g 'daemon off;'
|
||||||
process_name=%(program_name)s_%(process_num)02d
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
user=php-cli
|
user=root
|
||||||
numprocs=1
|
numprocs=1
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=false
|
autorestart=false
|
||||||
|
@ -17,7 +20,7 @@ stderr_logfile_maxbytes=0
|
||||||
[program:php-fpm]
|
[program:php-fpm]
|
||||||
command=php-fpm -F
|
command=php-fpm -F
|
||||||
process_name=%(program_name)s_%(process_num)02d
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
user=php-cli
|
user=root
|
||||||
numprocs=1
|
numprocs=1
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=false
|
autorestart=false
|
||||||
|
@ -27,34 +30,11 @@ stdout_logfile_maxbytes=0
|
||||||
stderr_logfile=/dev/stderr
|
stderr_logfile=/dev/stderr
|
||||||
stderr_logfile_maxbytes=0
|
stderr_logfile_maxbytes=0
|
||||||
|
|
||||||
; reads snappymail logs
|
|
||||||
[program:snappymail-auth]
|
|
||||||
command=tail -f /snappymail/data/_data_/_default_/logs/auth.log
|
|
||||||
stdout_logfile=/dev/stdout
|
|
||||||
stdout_logfile_maxbytes=0
|
|
||||||
stderr_logfile=/dev/stderr
|
|
||||||
stderr_logfile_maxbytes=0
|
|
||||||
|
|
||||||
[program:snappymail-errors]
|
|
||||||
command=tail -f /snappymail/data/_data_/_default_/logs/errors.log
|
|
||||||
# everything is an error
|
|
||||||
stdout_logfile=/dev/stderr
|
|
||||||
stdout_logfile_maxbytes=0
|
|
||||||
redirect_stderr=true
|
|
||||||
|
|
||||||
[program:logrotate]
|
|
||||||
command=/logrotate-loop.sh
|
|
||||||
autorestart=true
|
|
||||||
stdout_logfile=/dev/stdout
|
|
||||||
stdout_logfile_maxbytes=0
|
|
||||||
stderr_logfile=/dev/stderr
|
|
||||||
stderr_logfile_maxbytes=0
|
|
||||||
|
|
||||||
[eventlistener:subprocess-stopped]
|
[eventlistener:subprocess-stopped]
|
||||||
command=php /listener.php
|
command=php /listener.php
|
||||||
process_name=%(program_name)s_%(process_num)02d
|
process_name=%(program_name)s_%(process_num)02d
|
||||||
user=php-cli
|
user=root
|
||||||
numprocs=1
|
numprocs=1
|
||||||
events=PROCESS_STATE_EXITED,PROCESS_STATE_STOPPED,PROCESS_STATE_FATAL
|
events=PROCESS_STATE_EXITED,PROCESS_STATE_STOPPED,PROCESS_STATE_FATAL
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=unexpected
|
autorestart=unexpected
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
[global]
|
[global]
|
||||||
daemonize = no
|
daemonize = no
|
||||||
|
error_log = /dev/stderr
|
||||||
|
log_buffering = no
|
||||||
|
|
||||||
[default]
|
[default]
|
||||||
listen = /tmp/php-fpm.sock
|
listen = 9000
|
||||||
|
user = www-data
|
||||||
|
listen.owner = www-data
|
||||||
|
listen.group = www-data
|
||||||
pm = ondemand
|
pm = ondemand
|
||||||
pm.max_children = 30
|
pm.max_children = 30
|
||||||
pm.process_idle_timeout = 10s
|
pm.process_idle_timeout = 10s
|
||||||
pm.max_requests = 500
|
pm.max_requests = 500
|
||||||
catch_workers_output = yes
|
catch_workers_output = yes
|
||||||
|
decorate_workers_output = no
|
||||||
chdir = /
|
chdir = /
|
||||||
php_admin_value[error_log] = /tmp/php_error.log
|
pm.status_path = /status
|
||||||
php_admin_value[log_errors] = On
|
php_admin_value[log_errors] = On
|
||||||
php_admin_value[expose_php] = Off
|
php_admin_value[expose_php] = Off
|
||||||
php_admin_value[display_errors] = Off
|
php_admin_value[display_errors] = Off
|
||||||
|
|
7
.docker/release/test/build_and_test.sh
Executable file
7
.docker/release/test/build_and_test.sh
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# This script uses docker buildx to build a docker image, and loads it into the docker daemon. Then it executes ./test.sh to test the docker image
|
||||||
|
# It is useful for testing release builds in development
|
||||||
|
set -eu
|
||||||
|
IMAGE=snappymail/snappymail:test
|
||||||
|
DOCKER_BUILDX=1 docker build -t "$IMAGE" -f .docker/release/Dockerfile .
|
||||||
|
.docker/release/test/test.sh "$IMAGE"
|
29
.docker/release/test/config.yaml
Normal file
29
.docker/release/test/config.yaml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# See: https://github.com/GoogleContainerTools/container-structure-test
|
||||||
|
# See: https://github.com/GoogleContainerTools/container-structure-test/issues/78
|
||||||
|
schemaVersion: 2.0.0
|
||||||
|
commandTests:
|
||||||
|
- name: Integration test
|
||||||
|
command: /bin/sh
|
||||||
|
args:
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
set -eux
|
||||||
|
DEBUG=true /entrypoint.sh > /tmp/test 2>&1 &
|
||||||
|
sleep 5
|
||||||
|
cat /tmp/test
|
||||||
|
pidof supervisord
|
||||||
|
pidof nginx
|
||||||
|
pidof php-fpm
|
||||||
|
ls -al /var/lib/snappymail/_data_/_default_/configs/application.ini
|
||||||
|
ls -al /var/lib/snappymail/_data_/_default_/admin_password.txt
|
||||||
|
nc -vz localhost 8888
|
||||||
|
nc -vz localhost 9000
|
||||||
|
wget -S -T 3 -O /dev/null http://localhost:8888
|
||||||
|
kill `pidof supervisord`
|
||||||
|
metadataTest:
|
||||||
|
exposedPorts: ["8888", "9000"]
|
||||||
|
volumes: ["/var/lib/snappymail"]
|
||||||
|
entrypoint: []
|
||||||
|
cmd: ["/entrypoint.sh"]
|
||||||
|
workdir: /snappymail
|
||||||
|
user: root
|
10
.docker/release/test/test.sh
Executable file
10
.docker/release/test/test.sh
Executable file
|
@ -0,0 +1,10 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# This script tests a given docker image using https://github.com/GoogleContainerTools/container-structure-test
|
||||||
|
set -eu
|
||||||
|
SCRIPT_DIR=$( cd "$(dirname "$0")" && pwd )
|
||||||
|
IMAGE=${1:-}
|
||||||
|
echo "Testing image: $IMAGE"
|
||||||
|
docker run --rm -i \
|
||||||
|
-v /var/run/docker.sock:/var/run/docker.sock:ro \
|
||||||
|
-v "$SCRIPT_DIR/config.yaml:/config.yaml:ro" \
|
||||||
|
gcr.io/gcp-runtimes/container-structure-test:latest test --image "$IMAGE" --config config.yaml
|
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/.git
|
||||||
|
/node_modules
|
127
.github/workflows/docker.yml
vendored
Normal file
127
.github/workflows/docker.yml
vendored
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
name: docker
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
tags:
|
||||||
|
- '**'
|
||||||
|
# TODO: Remove this before merging PR
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
# This is needed to push to GitHub Container Registry. See https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# This step generates the docker tags
|
||||||
|
# TODO: Remove type=ref,event=pr before merging PR
|
||||||
|
- name: Docker meta
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v4
|
||||||
|
env:
|
||||||
|
# This env var ensures {{sha}} is a real commit SHA for type=ref,event=pr
|
||||||
|
DOCKER_METADATA_PR_HEAD_SHA: 'true'
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ github.repository }}
|
||||||
|
ghcr.io/${{ github.repository }}
|
||||||
|
# type=ref,event=pr generates tag(s) on PRs only. E.g. 'pr-123', 'pr-123-abc0123'
|
||||||
|
# type=ref,event=branch generates tag(s) on branch only. E.g. 'master', 'master-abc0123'
|
||||||
|
# type=ref,event=tag generates tag(s) on tags only. E.g. 'v0.0.0', 'v0.0.0-abc0123', and 'latest'
|
||||||
|
tags: |
|
||||||
|
type=ref,event=pr
|
||||||
|
type=ref,suffix=-{{sha}},event=pr
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,suffix=-{{sha}},event=branch
|
||||||
|
type=ref,event=tag
|
||||||
|
type=ref,suffix=-{{sha}},event=tag
|
||||||
|
# The rest of the org.opencontainers.image.xxx labels are dynamically generated
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.description=SnappyMail
|
||||||
|
org.opencontainers.image.licenses=AGPLv3
|
||||||
|
|
||||||
|
# See: https://github.com/docker/build-push-action/blob/v2.6.1/docs/advanced/cache.md#github-cache
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
id: buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
|
- name: Cache Docker layers
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: /tmp/.buildx-cache
|
||||||
|
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-buildx-
|
||||||
|
|
||||||
|
- name: Login to Docker Hub registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ghcr.io
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# See: https://github.com/docker/buildx/issues/59
|
||||||
|
- name: Build
|
||||||
|
id: build
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: '.'
|
||||||
|
file: ./.docker/release/Dockerfile
|
||||||
|
platforms: linux/amd64
|
||||||
|
push: false
|
||||||
|
load: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
|
|
||||||
|
- name: Docker images
|
||||||
|
run: |
|
||||||
|
docker images
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
TAG=$( echo "${{ steps.meta.outputs.tags }}" | head -n1 )
|
||||||
|
.docker/release/test/test.sh "$TAG"
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
id: build-and-push
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
context: '.'
|
||||||
|
file: ./.docker/release/Dockerfile
|
||||||
|
# TODO: Add more arches?
|
||||||
|
# platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/s390x
|
||||||
|
platforms: linux/386,linux/amd64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=local,src=/tmp/.buildx-cache
|
||||||
|
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
|
||||||
|
|
||||||
|
# Temp fix
|
||||||
|
# https://github.com/docker/build-push-action/issues/252
|
||||||
|
# https://github.com/moby/buildkit/issues/1896
|
||||||
|
- name: Move cache
|
||||||
|
run: |
|
||||||
|
rm -rf /tmp/.buildx-cache
|
||||||
|
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
|
@ -5,6 +5,10 @@
|
||||||
<br>
|
<br>
|
||||||
<h1>SnappyMail</h1>
|
<h1>SnappyMail</h1>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
[![github-actions](https://github.com/the-djmaze/snappymail/workflows/ci/badge.svg)](https://github.com/the-djmaze/snappymail/actions)
|
||||||
|
[![docker-image-size](https://img.shields.io/docker/image-size/the-djmaze/snappymail/master)](https://hub.docker.com/r/the-djmaze/snappymail)
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Simple, modern, lightweight & fast web-based email client.
|
Simple, modern, lightweight & fast web-based email client.
|
||||||
</p>
|
</p>
|
||||||
|
|
123
examples/README.md
Normal file
123
examples/README.md
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
Here are some [`docker-compose`] examples.
|
||||||
|
|
||||||
|
## `docker-compose.simple.yml`
|
||||||
|
|
||||||
|
This runs `snappymail`, using [SQLite](https://www.sqlite.org/index.html) as the database.
|
||||||
|
|
||||||
|
Start the stack:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker-compose -f docker-compose.simple.yml up
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the Admin Panel password:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker exec -it $( docker-compose -f docker-compose.simple.yml ps -q snappymail ) cat /var/lib/snappymail/_data_/_default_/admin_password.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, login to [http://localhost:8888/?admin](http://localhost:8888/?admin) with user `admin` and the admin password.
|
||||||
|
|
||||||
|
## `docker-compose.mysql.yml`
|
||||||
|
|
||||||
|
This runs `snappymail`, using [MariaDB](https://mariadb.org/) (a fork of [MYSQL](https://www.mysql.com/)) as the database.
|
||||||
|
|
||||||
|
Start `snappymail` and `mysql`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker-compose -f docker-compose.mysql.yml up
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the Admin Panel password:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker exec -it $( docker-compose -f docker-compose.mysql.yml ps -q snappymail ) cat /var/lib/snappymail/_data_/_default_/admin_password.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, login to [http://localhost:8888/?admin](http://localhost:8888/?admin) with user `admin` and the admin password.
|
||||||
|
|
||||||
|
To setup MySQL as the DB, in Admin Panel, click `Contacts`, check `Enable contacts` and , and under `Storage (PDO)` choose the following:
|
||||||
|
|
||||||
|
- Type: `MySQL`
|
||||||
|
- Data Source Name (DSN): `host=mysql;port=3306;dbname=snappymail`
|
||||||
|
- User `snappymail`
|
||||||
|
- Password `snappymail`
|
||||||
|
|
||||||
|
Click the `Test` button. If it turns green, MySQL is ready to be used for contacts.
|
||||||
|
|
||||||
|
To setup Redis for caching, in Admin Panel, click `Config`, update the following configuration options:
|
||||||
|
|
||||||
|
- `cache > enable`: yes
|
||||||
|
- `cache > fast_cache_driver`: `redis`
|
||||||
|
- `labs > fast_cache_redis_host`: `redis`
|
||||||
|
- `labs > fast_cache_redis_port`: `6379`
|
||||||
|
|
||||||
|
Redis caching is now enabled.
|
||||||
|
|
||||||
|
## `docker-compose.postgres.yml`
|
||||||
|
|
||||||
|
This runs `snappymail`, using [PostgreSQL](https://hub.docker.com/_/postgres) as the database.
|
||||||
|
|
||||||
|
Start `snappymail` and `postgres`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker-compose -f docker-compose.postgres.yml up
|
||||||
|
```
|
||||||
|
|
||||||
|
Get the Admin Panel password:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker exec -it $( docker-compose -f docker-compose.postgres.yml ps -q snappymail ) cat /var/lib/snappymail/_data_/_default_/admin_password.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, login to [http://localhost:8888/?admin](http://localhost:8888/?admin) with user `admin` and the admin password.
|
||||||
|
|
||||||
|
To use PostgreSQL as the DB, in Admin Panel, click `Contacts`, check `Enable contacts` and , and under `Storage (PDO)` choose the following:
|
||||||
|
|
||||||
|
- Type: `PostgresSQL`
|
||||||
|
- Data Source Name (DSN): `host=postgres;port=5432;dbname=snappymail`
|
||||||
|
- User `snappymail`
|
||||||
|
- Password `snappymail`
|
||||||
|
|
||||||
|
Click the `Test` button. If it turns green, PostgreSQL is ready to be used for contacts.
|
||||||
|
|
||||||
|
To setup Redis for caching, in Admin Panel, click `Config`, update the following configuration options:
|
||||||
|
|
||||||
|
- `cache > enable`: yes
|
||||||
|
- `cache > fast_cache_driver`: `redis`
|
||||||
|
- `labs > fast_cache_redis_host`: `redis`
|
||||||
|
- `labs > fast_cache_redis_port`: `6379`
|
||||||
|
|
||||||
|
Redis caching is now enabled.
|
||||||
|
|
||||||
|
## `docker-compose.traefik.yml`
|
||||||
|
|
||||||
|
This runs `snappymail`, using [SQLite](https://www.sqlite.org/index.html) as the database, with `traefik` as the TLS reverse proxy and loadbalancer.
|
||||||
|
|
||||||
|
In this example, it is assumed the domain name is `snappymail.example.com`. It is assumed you have an [OVHcloud](https://www.ovh.com/auth/) account to obtain LetsEncrypt TLS certs via `ACME` using DNS challenge for the domain `snappymail.example.com`. If you are using another DNS provider, see [here](https://doc.traefik.io/traefik/https/acme/#providers).
|
||||||
|
|
||||||
|
To begin, edit the `OVH_*` environment variables in [`docker-compose.traefik.yml`](docker-compose.traefik.yml) accordingly:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nano docker-compose.traefik.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
Start `snappymail` and `traefik`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker-compose -f docker-compose.traefik.yml up
|
||||||
|
```
|
||||||
|
|
||||||
|
`traefik` should now begin requesting a TLS cert for `snappymail.example.com`. The process may take a few minutes. If all goes well, https://snappymail.example.com should now be ready.
|
||||||
|
|
||||||
|
> You may still visit https://snappymail.example.com while waiting for `traefik` to be issued a TLS certificate. `traefik` simply serves a self-signed TLS cert.
|
||||||
|
|
||||||
|
Get the Admin Panel password:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker exec -it $( docker-compose -f docker-compose.traefik.yml ps -q snappymail ) cat /var/lib/snappymail/_data_/_default_/admin_password.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
Now, login to [https://snappymail.example.com/?admin](https://snappymail.example.com/?admin) with user `admin` and the admin password.
|
57
examples/docker-compose.mysql.yml
Normal file
57
examples/docker-compose.mysql.yml
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
snappymail:
|
||||||
|
image: leojonathanoh/snappymail:pr-1
|
||||||
|
ports:
|
||||||
|
- 8888:8888
|
||||||
|
environment:
|
||||||
|
- DEBUG=true
|
||||||
|
volumes:
|
||||||
|
- snappymail:/var/lib/snappymail
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- db-network
|
||||||
|
- redis-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# This provides prometheus metrics for snappymail's php-fpm
|
||||||
|
php-fpm-exporter:
|
||||||
|
image: hipages/php-fpm_exporter:2.2.0
|
||||||
|
ports:
|
||||||
|
- 9253:9253
|
||||||
|
environment:
|
||||||
|
- PHP_FPM_SCRAPE_URI=tcp://snappymail:9000/status
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mariadb:10
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=root
|
||||||
|
- MYSQL_USER=snappymail
|
||||||
|
- MYSQL_PASSWORD=snappymail
|
||||||
|
- MYSQL_DATABASE=snappymail
|
||||||
|
volumes:
|
||||||
|
- mysql:/var/lib/mysql
|
||||||
|
networks:
|
||||||
|
- db-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
networks:
|
||||||
|
- redis-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
db-network:
|
||||||
|
internal: true
|
||||||
|
redis-network:
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql:
|
||||||
|
driver: local
|
||||||
|
snappymail:
|
||||||
|
driver: local
|
56
examples/docker-compose.postgres.yml
Normal file
56
examples/docker-compose.postgres.yml
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
snappymail:
|
||||||
|
image: leojonathanoh/snappymail:pr-1
|
||||||
|
ports:
|
||||||
|
- 8888:8888
|
||||||
|
environment:
|
||||||
|
- DEBUG=true
|
||||||
|
volumes:
|
||||||
|
- snappymail:/var/lib/snappymail
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- db-network
|
||||||
|
- redis-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# This provides prometheus metrics for snappymail's php-fpm
|
||||||
|
php-fpm-exporter:
|
||||||
|
image: hipages/php-fpm_exporter:2.2.0
|
||||||
|
ports:
|
||||||
|
- 9253:9253
|
||||||
|
environment:
|
||||||
|
- PHP_FPM_SCRAPE_URI=tcp://snappymail:9000/status
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
environment:
|
||||||
|
- POSTGRES_USER=snappymail
|
||||||
|
- POSTGRES_PASSWORD=snappymail
|
||||||
|
- POSTGRES_DB=snappymail
|
||||||
|
volumes:
|
||||||
|
- postgres:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- db-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
networks:
|
||||||
|
- redis-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
db-network:
|
||||||
|
internal: true
|
||||||
|
redis-network:
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres:
|
||||||
|
driver: local
|
||||||
|
snappymail:
|
||||||
|
driver: local
|
30
examples/docker-compose.simple.yml
Normal file
30
examples/docker-compose.simple.yml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
snappymail:
|
||||||
|
image: leojonathanoh/snappymail:pr-1
|
||||||
|
ports:
|
||||||
|
- 8888:8888
|
||||||
|
environment:
|
||||||
|
- DEBUG=true
|
||||||
|
volumes:
|
||||||
|
- snappymail:/var/lib/snappymail
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# This provides prometheus metrics for snappymail's php-fpm
|
||||||
|
php-fpm-exporter:
|
||||||
|
image: hipages/php-fpm_exporter:2.2.0
|
||||||
|
ports:
|
||||||
|
- 9253:9253
|
||||||
|
environment:
|
||||||
|
- PHP_FPM_SCRAPE_URI=tcp://snappymail:9000/status
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
snappymail:
|
||||||
|
driver: local
|
86
examples/docker-compose.traefik.yml
Normal file
86
examples/docker-compose.traefik.yml
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
version: '2'
|
||||||
|
services:
|
||||||
|
# The reverse proxy for our web containers
|
||||||
|
# See https://github.com/traefik/traefik/tree/v2.7/docs/content/user-guides/docker-compose for some examples for enabling HTTPS using ACME
|
||||||
|
# You will need a domain name. E.g. 'example.com'
|
||||||
|
# This example requests TLS certs via ACME via DNS challenge using OVHcloud as the DNS provider.
|
||||||
|
# For a list of supported DNS providers, see: https://doc.traefik.io/traefik/https/acme/#providers
|
||||||
|
traefik:
|
||||||
|
image: traefik:v2
|
||||||
|
environment:
|
||||||
|
- OVH_ENDPOINT=xxx
|
||||||
|
- OVH_APPLICATION_KEY=xxx
|
||||||
|
- OVH_APPLICATION_SECRET=xxx
|
||||||
|
- OVH_CONSUMER_KEY=xxx
|
||||||
|
volumes:
|
||||||
|
# Allow traefik to listen to the Docker events
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
|
- acme-volume:/letsencrypt
|
||||||
|
ports:
|
||||||
|
- 80:80
|
||||||
|
- 443:443
|
||||||
|
networks:
|
||||||
|
- traefik-network
|
||||||
|
restart: unless-stopped
|
||||||
|
command:
|
||||||
|
- --global.checknewversion=false
|
||||||
|
- --global.sendanonymoususage=false
|
||||||
|
# - --log.level=DEBUG
|
||||||
|
- --providers.docker=true
|
||||||
|
- --providers.docker.exposedbydefault=false
|
||||||
|
- --entrypoints.web.address=:80
|
||||||
|
- --entrypoints.websecure.address=:443
|
||||||
|
- --certificatesresolvers.myresolver.acme.dnschallenge=true
|
||||||
|
- --certificatesresolvers.myresolver.acme.dnschallenge.provider=ovh
|
||||||
|
# - --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
- --certificatesresolvers.myresolver.acme.email=postmaster@example.com
|
||||||
|
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
|
||||||
|
|
||||||
|
# snappymail will be available at: https://snappymail.example.com
|
||||||
|
snappymail:
|
||||||
|
image: leojonathanoh/snappymail:pr-1
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.docker.network=traefik-network"
|
||||||
|
# traefik v2
|
||||||
|
# http
|
||||||
|
- "traefik.http.routers.snappymail-http.entrypoints=web"
|
||||||
|
- "traefik.http.routers.snappymail-http.rule=Host(`snappymail.example.com`)"
|
||||||
|
- "traefik.http.routers.snappymail-http.middlewares=snappymail-http-myRedirectScheme" # Redirect http to https
|
||||||
|
- "traefik.http.middlewares.snappymail-http-myRedirectScheme.redirectScheme.scheme=https" # Redirect http to https
|
||||||
|
# https
|
||||||
|
- "traefik.http.routers.snappymail.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.snappymail.tls"
|
||||||
|
- "traefik.http.routers.snappymail.rule=Host(`snappymail.example.com`)"
|
||||||
|
- "traefik.http.services.snappymail.loadbalancer.server.port=8888"
|
||||||
|
expose:
|
||||||
|
- 8888
|
||||||
|
environment:
|
||||||
|
- DEBUG=true
|
||||||
|
volumes:
|
||||||
|
- snappymail:/var/lib/snappymail
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- traefik-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# This provides prometheus metrics for snappymail's php-fpm
|
||||||
|
php-fpm-exporter:
|
||||||
|
image: hipages/php-fpm_exporter:2.2.0
|
||||||
|
ports:
|
||||||
|
- 9253:9253
|
||||||
|
environment:
|
||||||
|
- PHP_FPM_SCRAPE_URI=tcp://snappymail:9000/status
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
traefik-network:
|
||||||
|
name: traefik-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
acme-volume:
|
||||||
|
driver: local
|
||||||
|
snappymail:
|
||||||
|
driver: local
|
Loading…
Reference in a new issue