Docker Mailserver and Rainloop Webclient
Jump to navigation
Jump to search
Docker Mailserver and Rainloop Webclient
Fully dockerized email server and dockerized Rainloop webmail client setup
- Mail server used: https://github.com/docker-mailserver/docker-mailserver
- Modified Rainloop used: https://github.com/Hermsi1337/docker-rainloop
- And using JWilder's NGINX proxy: https://github.com/nginx-proxy/nginx-proxy
NGINX Proxy
docker-compose.yml
version: '2' services: nginx-proxy: image: jwilder/nginx-proxy container_name: nginx-proxy environment: - "HTTPS_METHOD=noredirect" labels: - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy" ports: - "80:80" - "443:443" restart: always volumes: - "./data/etc/certs:/etc/nginx/certs" - "./data/etc/nginx/vhost.d:/etc/nginx/vhost.d" - "./data/etc/nginx/htpasswd:/etc/nginx/htpasswd" - "./data/etc/nginx/html:/usr/share/nginx/html" - "/var/run/docker.sock:/tmp/docker.sock:ro" letsencrypt: image: jrcs/letsencrypt-nginx-proxy-companion environment: ### ToDo: Change to your e-mail address # - DEFAULT_EMAIL=admin@demo.io - NGINX_PROXY_CONTAINER=nginx-proxy volumes_from: - nginx-proxy volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./data/etc/certs:/etc/nginx/certs:rw restart: always networks: default: external: name: nginx-proxy
- Create nginx-proxy network:
docker network create nginx-proxy
Docker-Mailserver
Follow the https://github.com/docker-mailserver/docker-mailserver#get-the-tools link, but use the docker-compose.yml file below instead of the one in the repo.
Edit mailserver.env as required for the settings you want/need
docker-compose.yml
version: '3.8' services: mailserver: image: docker.io/mailserver/docker-mailserver:latest hostname: <domain> domainname: <domain> container_name: mail env_file: mailserver.env ports: - "25:25" - "143:143" - "587:587" - "993:993" volumes: - ./data/mail:/var/mail - ./data/mail-state:/var/mail-state - ./log:/var/log/mail - ./config/:/tmp/docker-mailserver #- ./config/:/tmp/docker-mailserver/${SELINUX_LABEL} - /etc/letsencrypt:/etc/letsencrypt restart: always cap_add: [ "NET_ADMIN", "SYS_PTRACE" ] volumes: maildata: mailstate: maillogs:
Get Up and Running
docker-compose up -d mailserver # for SELinux, use -Z ./setup.sh [-Z] email add <user@domain> [<password>] ./setup.sh [-Z] alias add postmaster@<domain> <user@domain> ./setup.sh [-Z] config dkim
Rainloop
A slightly modified version of what is in the Github repo shown in the Introduction section
docker-compose.yml
version: '3' volumes: rainloop-root: # rainloop-data: # driver: default-driver # driver_opts: # mountpoint: ./data/rainloop/data services: webserver: image: nginx:alpine volumes: - ./config/nginx.conf:/etc/nginx/nginx.conf:ro - rainloop-root:/rainloop depends_on: - application environment: - VIRTUAL_HOST=<domain> # - VIRTUAL_PROTO=https # - VIRTUAL_PORT=443 - HTTPS_METHOD=nohttp - LETSENCRYPT_HOST=<domain> - LETSENCRYPT_EMAIL=<admin email> restart: always networks: - default - nginxproxy application: # image: hermsi/alpine-rainloop build: . volumes: - rainloop-root:/rainloop - ./data/rainloop-data:/rainloop/data restart: always networks: default: aliases: - rainloop networks: nginxproxy: external: name: nginx-proxy
Dockerfile
FROM hermsi/alpine-fpm-php LABEL maintainer "https://github.com/hermsi1337" # Get some stuff in order to work properly RUN apk --no-cache --update --virtual .build-dependencies add gnupg openssl wget zip \ && update-ca-certificates # Download and install RainLoop ENV RAINLOOP_ROOT="/rainloop" ARG GPG_FINGERPRINT="3B79 7ECE 694F 3B7B 70F3 11A4 ED7C 49D9 87DA 4591" RUN export TMP_DIR="/tmp" && \ export RAINLOOP_ZIP="${TMP_DIR}/RainLoop.zip" && \ export RAINLOOP_ZIP_ASC="${RAINLOOP_ZIP}.asc" && \ export RAINLOOP_ASC="${TMP_DIR}/RainLoop.asc" && \ wget -q "https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip" -O "${RAINLOOP_ZIP}" && \ wget -q "https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip.asc" -O "${RAINLOOP_ZIP_ASC}" && \ wget -q "https://www.rainloop.net/repository/RainLoop.asc" -O "${RAINLOOP_ASC}" && \ gpg --import "${RAINLOOP_ASC}" && \ FINGERPRINT="$(LANG=C gpg --verify ${RAINLOOP_ZIP_ASC} ${RAINLOOP_ZIP} 2>&1 \ | sed -n "s#Primary key fingerprint: \(.*\)#\1#p")" && \ if [ -z "${FINGERPRINT}" ]; then echo "Warning! Invalid GPG signature!" && exit 1; fi && \ if [ "${FINGERPRINT}" != "${GPG_FINGERPRINT}" ]; then echo "Warning! Wrong GPG fingerprint!" && exit 1; fi && \ mkdir "${RAINLOOP_ROOT}" && \ unzip -q "${RAINLOOP_ZIP}" -d "${RAINLOOP_ROOT}" && \ apk del .build-dependencies && \ rm -rf "${TMP_DIR}/*" "/var/cache/apk/*" "/root/.gnupg" # Take care of additional configuration stuff ENV MEMORY_LIMIT="128M" \ UPLOAD_MAX_FILESIZE="32M" \ POST_MAX_SIZE="64M" RUN chown "www-data." "${RAINLOOP_ROOT}" -R && \ find "${RAINLOOP_ROOT}" -type d -exec chmod 755 {} \; && \ find "${RAINLOOP_ROOT}" -type f -exec chmod 644 {} \; && \ printf "%s\n%s\n%s" "memory_limit = ${MEMORY_LIMIT}" "upload_max_filesize = ${UPLOAD_MAX_FILESIZE}" "post_max_size = ${POST_MAX_SIZE}" > "${RAINLOOP_ROOT}/.user.ini"; \
- Make a config/ directory and place the following file into it:
nginx.conf
events { worker_connections 768; } http { upstream backend { server rainloop:9000; } include /etc/nginx/mime.types; default_type application/octet-stream; gzip on; gzip_disable "msie6"; server { listen 80 default; server_name rainloop; root /rainloop; index index.php index.html; charset utf-8; location / { try_files $uri $uri/ index.php; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } sendfile off; location ~* \.php$ { fastcgi_index index.php; fastcgi_pass rainloop:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } location ~ /\.ht { deny all; } location ^~ /data { deny all; } client_max_body_size 1G; } }
Upgrading
- Rename ./data to ./data-old
- Delete rainloop-root volume
docker volume rm rainloop_rainloop-root
- Re-build Docker image
docker-compose build