From 2b82a0dc87b22fe4c6e3effa99dcd2c1e3f9cc97 Mon Sep 17 00:00:00 2001 From: Davide Polonio Date: Tue, 14 Jul 2020 09:07:33 +0000 Subject: [PATCH] First commit --- .gitignore | 3 + README.md | 6 + mail/docker-compose.yml | 51 +++++ mail/setup.sh | 346 ++++++++++++++++++++++++++++++ reverse_proxy/docker-compose.yaml | 54 +++++ 5 files changed, 460 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 mail/docker-compose.yml create mode 100755 mail/setup.sh create mode 100644 reverse_proxy/docker-compose.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4b4a85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +env-mailserver +config/ +.env diff --git a/README.md b/README.md new file mode 100644 index 0000000..3e55c4d --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +Poldebra cloud configuration dotfiles +=== + +This repository contains all the configuration files for the cloud services offered by this server. +These configs are versioned so that it is possible to move between versions without assle. +Note: .env and other related env/config folders are not committed here for security reasons. diff --git a/mail/docker-compose.yml b/mail/docker-compose.yml new file mode 100644 index 0000000..a691d25 --- /dev/null +++ b/mail/docker-compose.yml @@ -0,0 +1,51 @@ +version: '2' +services: + mail: + image: tvial/docker-mailserver:latest + hostname: ${HOSTNAME} + domainname: ${DOMAINNAME} + container_name: ${CONTAINER_NAME} + ports: + - "25:25" + - "143:143" + - "587:587" + - "993:993" + volumes: + - maildata:/var/mail + - mailstate:/var/mail-state + - maillogs:/var/log/mail + - ./config/:/tmp/docker-mailserver/ + - nginx_cert:/etc/letsencrypt/live/mail.poldebra.me + env_file: + - .env + - env-mailserver + cap_add: + - NET_ADMIN + - SYS_PTRACE + restart: always + +volumes: + maildata: + driver: local + driver_opts: + type: none + o: bind + device: "/srv/docker/mail/data" + mailstate: + driver: local + driver_opts: + type: none + o: bind + device: "/srv/docker/mail/state" + maillogs: + driver: local + driver_opts: + type: none + o: bind + device: "/srv/docker/mail/logs" + nginx_cert: + driver: local + driver_opts: + type: none + o: bind + device: "/srv/docker/reverse_proxy/certs/mail.poldebra.me" diff --git a/mail/setup.sh b/mail/setup.sh new file mode 100755 index 0000000..ac2d7e2 --- /dev/null +++ b/mail/setup.sh @@ -0,0 +1,346 @@ +#!/bin/sh + +## +# Wrapper for various setup scripts included in the docker-mailserver +# + +CRI= + +_check_root() { + if [[ $EUID -ne 0 ]]; then + echo "Curently docker-mailserver doesn't support podman's rootless mode, please run this script as root user." + exit 1 + fi +} + +if [ -z "$CRI" ]; then + if [ ! -z "$(command -v docker)" ]; then + CRI=docker + elif [ ! -z "$(command -v podman)" ]; then + CRI=podman + _check_root + else + echo "No Support Container Runtime Interface Detected." + exit 1 + fi +fi + +INFO=$($CRI ps \ + --no-trunc \ + --format "{{.Image}};{{.Names}}" \ + --filter label=org.label-schema.name="docker-mailserver" | \ + tail -1) + +IMAGE_NAME=${INFO%;*} +CONTAINER_NAME=${INFO#*;} +DEFAULT_CONFIG_PATH="$(pwd)/config" +USE_CONTAINER=false + +_update_config_path() { + if [ ! -z "$CONTAINER_NAME" ]; then + VOLUME=$(docker inspect $CONTAINER_NAME \ + --format="{{range .Mounts}}{{ println .Source .Destination}}{{end}}" | \ + grep "/tmp/docker-mailserver$" 2>/dev/null) + fi + + if [ ! -z "$VOLUME" ]; then + CONFIG_PATH=$(echo $VOLUME | awk '{print $1}') + fi +} + +if [ -z "$IMAGE_NAME" ]; then + if [ "$CRI" = "docker" ]; then + IMAGE_NAME=tvial/docker-mailserver:latest + elif [ "$CRI" = "podman" ]; then + IMAGE_NAME=docker.io/tvial/docker-mailserver:latest + fi +fi + +_inspect() { + if _docker_image_exists "$IMAGE_NAME"; then + echo "Image: $IMAGE_NAME" + else + echo "Image: '$IMAGE_NAME' can’t be found." + fi + if [ -n "$CONTAINER_NAME" ]; then + echo "Container: $CONTAINER_NAME" + echo "Config mount: $CONFIG_PATH" + else + echo "Container: Not running, please start docker-mailserver." + fi +} + +_usage() { + echo "Usage: $0 [-i IMAGE_NAME] [-c CONTAINER_NAME] [args] + +OPTIONS: + + -i IMAGE_NAME The name of the docker-mailserver image, by default + 'tvial/docker-mailserver:latest' for docker, and + 'docker.io/tvial/docker-mailserver:latest' for podman. + + -c CONTAINER_NAME The name of the running container. + + -p PATH config folder path (default: $(pwd)/config) + +SUBCOMMANDS: + + email: + + $0 email add [] + $0 email update [] + $0 email del + $0 email restrict [] + $0 email list + + alias: + $0 alias add + $0 alias del + $0 alias list + + quota: + $0 quota set [] + $0 quota del + + config: + + $0 config dkim (default: 2048) + $0 config ssl + + relay: + + $0 relay add-domain [] + $0 relay add-auth [] + $0 relay exclude-domain + + debug: + + $0 debug fetchmail + $0 debug fail2ban [ ] + $0 debug show-mail-logs + $0 debug inspect + $0 debug login +" + exit 1 +} + +_docker_image_exists() { + if ${CRI} history -q "$1" >/dev/null 2>&1; then + return 0 + else + return 1 + fi +} + +if tty -s ; then + USE_TTY="-ti" +fi + +_docker_image() { + if [ "$USE_CONTAINER" = true ]; then + # Reuse existing container specified on command line + ${CRI} exec ${USE_TTY} "$CONTAINER_NAME" "$@" + else + # Start temporary container with specified image + if ! _docker_image_exists "$IMAGE_NAME"; then + echo "Image '$IMAGE_NAME' not found. Pulling ..." + ${CRI} pull "$IMAGE_NAME" + fi + + ${CRI} run \ + --rm \ + -v "$CONFIG_PATH":/tmp/docker-mailserver \ + ${USE_TTY} "$IMAGE_NAME" $@ + fi +} + +_docker_container() { + if [ -n "$CONTAINER_NAME" ]; then + ${CRI} exec ${USE_TTY} "$CONTAINER_NAME" "$@" + else + echo "The docker-mailserver is not running!" + exit 1 + fi +} + +while getopts ":c:i:p:" OPT; do + case $OPT in + c) + CONTAINER_NAME="$OPTARG" + USE_CONTAINER=true # Container specified, connect to running instance + ;; + i) + IMAGE_NAME="$OPTARG" + ;; + p) + case "$OPTARG" in + /*) + WISHED_CONFIG_PATH="$OPTARG" + ;; + *) + WISHED_CONFIG_PATH="$(pwd)/$OPTARG" + ;; + esac + if [ ! -d "$WISHED_CONFIG_PATH" ]; then + echo "Directory doesn't exist" + _usage + exit 1 + fi + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + ;; + esac +done + +if [ ! -n "$WISHED_CONFIG_PATH" ]; then + # no wished config path + _update_config_path + + if [ ! -n "$CONFIG_PATH" ]; then + CONFIG_PATH=$DEFAULT_CONFIG_PATH + fi +else + CONFIG_PATH=$WISHED_CONFIG_PATH +fi + +shift $((OPTIND-1)) + +case $1 in + + email) + shift + case $1 in + add) + shift + _docker_image addmailuser $@ + ;; + update) + shift + _docker_image updatemailuser $@ + ;; + del) + shift + _docker_image delmailuser $@ + ;; + restrict) + shift + _docker_container restrict-access $@ + ;; + list) + _docker_image listmailuser + ;; + *) + _usage + ;; + esac + ;; + + alias) + shift + case $1 in + add) + shift + _docker_image addalias $@ + ;; + del) + shift + _docker_image delalias $@ + ;; + list) + shift + _docker_image listalias $@ + ;; + *) + _usage + ;; + esac + ;; + + quota) + shift + case $1 in + set) + shift + _docker_image setquota $@ + ;; + del) + shift + _docker_image delquota $@ + ;; + *) + _usage + ;; + esac + ;; + + config) + shift + case $1 in + dkim) + _docker_image generate-dkim-config $2 + ;; + ssl) + _docker_image generate-ssl-certificate "$2" + ;; + *) + _usage + ;; + esac + ;; + + relay) + shift + case $1 in + add-domain) + shift + _docker_image addrelayhost $@ + ;; + add-auth) + shift + _docker_image addsaslpassword $@ + ;; + exclude-domain) + shift + _docker_image excluderelaydomain $@ + ;; + *) + _usage + ;; + esac + ;; + + debug) + shift + case $1 in + fetchmail) + _docker_image debug-fetchmail + ;; + fail2ban) + shift + _docker_container fail2ban $@ + ;; + show-mail-logs) + _docker_container cat /var/log/mail/mail.log + ;; + inspect) + _inspect + ;; + login) + shift + if [ -z "$1" ]; then + _docker_container /bin/bash + else + _docker_container /bin/bash -c "$@" + fi + ;; + *) + _usage + ;; + esac + ;; + + *) + _usage + ;; +esac diff --git a/reverse_proxy/docker-compose.yaml b/reverse_proxy/docker-compose.yaml new file mode 100644 index 0000000..aaf3f19 --- /dev/null +++ b/reverse_proxy/docker-compose.yaml @@ -0,0 +1,54 @@ +version: '3.7' +services: + nginx: + image: jwilder/nginx-proxy + restart: always + ports: + - 80:80 + - 443:443 + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + - nginx_cert:/etc/nginx/certs + - nginx_vhost:/etc/nginx/vhost.d + - nginx_html:/usr/share/nginx/html + labels: + - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy" + networks: + - proxy + + nginx-letsencript: + image: jrcs/letsencrypt-nginx-proxy-companion + restart: always + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - nginx_cert:/etc/nginx/certs + - nginx_vhost:/etc/nginx/vhost.d + - nginx_html:/usr/share/nginx/html + networks: + - proxy + + web: + image: nginx + environment: + - NGINX_HOST=mail.poldebra.me + - NGINX_PORT=80 + - VIRTUAL_HOST=mail.poldebra.me + - VIRTUAL_PORT=80 + - LETSENCRYPT_HOST=mail.poldebra.me + - LETSENCRYPT_EMAIL=poloniodavide@gmail.com + networks: + - proxy + +volumes: + nginx_cert: + driver: local + driver_opts: + type: none + o: bind + device: "/srv/docker/reverse_proxy/certs" + nginx_vhost: + nginx_html: + +networks: + proxy: + external: true