forked from the-djmaze/snappymail
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add better Docker development and prod support
- Loading branch information
Showing
27 changed files
with
1,453 additions
and
66 deletions.
There are no files selected for viewing
File renamed without changes.
0
.docker/mail/setup.sh → .docker/dev/mail/setup.sh
100755 → 100644
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
|
||
server { | ||
listen 80 default; | ||
listen 443 ssl; | ||
|
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Inspired by the original Rainloop dockerfile from youtous on GitLab | ||
FROM php:7.3-fpm-buster | ||
|
||
ARG FILES_ZIP | ||
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=50M LOG_TO_STDERR=true MEMORY_LIMIT=128M SECURE_COOKIES=true | ||
ENV fpm.pool.clear_env=false | ||
|
||
# Install dependencies such as nginx | ||
RUN mkdir -p /usr/share/man/man1/ /usr/share/man/man3/ /usr/share/man/man7/ && \ | ||
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 libmcrypt-dev 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 | ||
RUN php -m && \ | ||
docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ && \ | ||
docker-php-ext-configure intl && \ | ||
docker-php-ext-configure gd --with-freetype-dir=/usr/include --with-jpeg-dir=/usr/include/ && \ | ||
docker-php-ext-install ldap opcache pdo_mysql pdo_pgsql zip intl gd && \ | ||
php -m | ||
|
||
# Install snappymail | ||
WORKDIR /tmp | ||
COPY ${FILES_ZIP} . | ||
RUN mkdir /snappymail && \ | ||
unzip -q ${FILES_ZIP} -d /snappymail && \ | ||
find /snappymail -type d -exec chmod 755 {} \; && \ | ||
find /snappymail -type f -exec chmod 644 {} \; && \ | ||
rm -rf ${FILES_ZIP} | ||
|
||
# Install other content | ||
COPY files / | ||
RUN chmod +x /entrypoint.sh && chmod +x /logrotate-loop.sh | ||
VOLUME /snappymail/data | ||
EXPOSE 8888 | ||
CMD ["/entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#!/bin/sh | ||
|
||
# Create not root user | ||
groupadd --gid "$GID" php-cli -f | ||
adduser --uid "$UID" --disabled-password --gid "$GID" --shell /bin/bash --home /home/php-cli php-cli --force --gecos "" | ||
|
||
|
||
# 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/<MEMORY_LIMIT>/$MEMORY_LIMIT/g" /usr/local/etc/php-fpm.d/php-fpm.conf | ||
|
||
# Remove postfixadmin-change-password plugin if exist | ||
if [ -d "/snappymail/data/_data_/_default_/plugins/postfixadmin-change-password" ]; then | ||
rm -rf /snappymail/data/_data_/_default_/plugins/postfixadmin-change-password | ||
fi | ||
|
||
# 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 | ||
if [ "${SECURE_COOKIES}" = true ]; then | ||
echo "[INFO] Secure cookies activated" | ||
{ | ||
echo 'session.cookie_httponly = On'; | ||
echo 'session.cookie_secure = On'; | ||
echo 'session.use_only_cookies = On'; | ||
} > /usr/local/etc/php/conf.d/cookies.ini; | ||
fi | ||
|
||
# Add postfixadmin-change-password plugin | ||
mkdir -p /snappymail/data/_data_/_default_/plugins/ | ||
cp -r /usr/local/include/postfixadmin-change-password /snappymail/data/_data_/_default_/plugins/ | ||
|
||
# Copy snappymail default config if absent | ||
SNAPPYMAIL_CONFIG_FILE=/snappymail/data/_data_/_default_/configs/application.ini | ||
if [ ! -f "$SNAPPYMAIL_CONFIG_FILE" ]; then | ||
echo "[INFO] Creating default Snappymail configuration" | ||
mkdir -p $(dirname $SNAPPYMAIL_CONFIG_FILE) | ||
cp /usr/local/include/application.ini $SNAPPYMAIL_CONFIG_FILE | ||
fi | ||
|
||
# Enable output of snappymail logs | ||
if [ "${LOG_TO_STDERR}" = true ]; then | ||
sed -z 's/\; Enable logging\nenable = Off/\; Enable logging\nenable = On/' -i $SNAPPYMAIL_CONFIG_FILE | ||
sed 's/^filename = .*/filename = "errors.log"/' -i $SNAPPYMAIL_CONFIG_FILE | ||
sed 's/^write_on_error_only = .*/write_on_error_only = Off/' -i $SNAPPYMAIL_CONFIG_FILE | ||
sed 's/^write_on_php_error_only = .*/write_on_php_error_only = On/' -i $SNAPPYMAIL_CONFIG_FILE | ||
else | ||
sed -z 's/\; Enable logging\nenable = On/\; Enable logging\nenable = Off/' -i $SNAPPYMAIL_CONFIG_FILE | ||
fi | ||
# Always enable snappymail Auth logging | ||
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_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 | ||
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 | ||
chmod o+w /dev/stdout | ||
chmod o+w /dev/stderr | ||
|
||
|
||
# Touch supervisord PID file in order to fix permissions | ||
touch /run/supervisord.pid | ||
chown php-cli:php-cli /run/supervisord.pid | ||
|
||
# RUN ! | ||
exec sudo -u php-cli -g php-cli /usr/bin/supervisord -c '/supervisor.conf' --pidfile '/run/supervisord.pid' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/snappymail/data/_data_/_default_/logs/* { | ||
size 10M | ||
rotate 0 | ||
missingok | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
worker_processes auto; | ||
pid /tmp/nginx.pid; | ||
|
||
events { | ||
worker_connections 1024; | ||
use epoll; | ||
} | ||
|
||
http { | ||
include /etc/nginx/mime.types; | ||
default_type application/octet-stream; | ||
|
||
access_log off; | ||
error_log /tmp/ngx_error.log error; | ||
|
||
sendfile on; | ||
keepalive_timeout 15; | ||
keepalive_disable msie6; | ||
keepalive_requests 100; | ||
tcp_nopush on; | ||
tcp_nodelay on; | ||
server_tokens off; | ||
|
||
fastcgi_temp_path /tmp/fastcgi 1 2; | ||
client_body_temp_path /tmp/client_body 1 2; | ||
proxy_temp_path /tmp/proxy 1 2; | ||
uwsgi_temp_path /tmp/uwsgi 1 2; | ||
scgi_temp_path /tmp/scgi 1 2; | ||
|
||
gzip on; | ||
gzip_comp_level 5; | ||
gzip_min_length 512; | ||
gzip_buffers 4 8k; | ||
gzip_proxied any; | ||
gzip_vary on; | ||
gzip_disable "msie6"; | ||
gzip_types | ||
text/css | ||
text/javascript | ||
text/xml | ||
text/plain | ||
text/x-component | ||
application/javascript | ||
application/x-javascript | ||
application/json | ||
application/xml | ||
application/rss+xml | ||
application/vnd.ms-fontobject | ||
font/truetype | ||
font/opentype | ||
image/svg+xml; | ||
|
||
server { | ||
listen 8888; | ||
root /snappymail; | ||
index index.php; | ||
charset utf-8; | ||
|
||
client_max_body_size <UPLOAD_MAX_SIZE>; | ||
|
||
location ^~ /data { | ||
deny all; | ||
} | ||
|
||
location / { | ||
try_files $uri $uri/ index.php; | ||
} | ||
|
||
# Assets cache control | ||
# -------------------------------------- | ||
location ~* \.(?:html|xml|json)$ { | ||
expires -1; | ||
} | ||
|
||
location ~* \.(?:css|js)$ { | ||
expires 7d; | ||
add_header Pragma public; | ||
add_header Cache-Control "public"; | ||
} | ||
|
||
location ~* \.(?:gif|jpe?g|png|ico|otf|eot|svg|ttf|woff|woff2)$ { | ||
expires 30d; | ||
log_not_found off; | ||
add_header Pragma public; | ||
add_header Cache-Control "public"; | ||
} | ||
|
||
# PHP Backend | ||
# -------------------------------------- | ||
location ~* \.php$ { | ||
try_files $uri =404; | ||
include fastcgi_params; | ||
fastcgi_split_path_info ^(.+\.php)(/.*)$; | ||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | ||
fastcgi_param PATH_INFO $fastcgi_path_info; | ||
fastcgi_param HTTP_PROXY ""; | ||
fastcgi_index index.php; | ||
fastcgi_pass unix:/tmp/php-fpm.sock; | ||
fastcgi_intercept_errors on; | ||
fastcgi_request_buffering off; | ||
fastcgi_param REMOTE_ADDR $http_x_real_ip; | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
$stdIn = STDIN; | ||
$stdOut = STDOUT; | ||
|
||
fwrite($stdOut, "READY\n"); | ||
|
||
while(true) { | ||
if (false == $line = trim(fgets($stdIn))) { | ||
continue; | ||
} | ||
|
||
$match = null; | ||
if (preg_match('/eventname:(.*?) /', $line, $match)) { | ||
if (in_array($match[1], ['PROCESS_STATE_EXITED', 'PROCESS_STATE_STOPPED', 'PROCESS_STATE_FATAL'])) { | ||
exec('kill -15 '.file_get_contents('/run/supervisord.pid')); | ||
} | ||
} | ||
|
||
fwrite($stdOut, "RESULT 2\nOK"); | ||
|
||
sleep(1); | ||
fwrite($stdOut, "READY\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#!/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} |
Oops, something went wrong.