diff --git a/bin/quickstart.sh b/bin/quickstart.sh index 4dd80d2b..dc9c2b21 100755 --- a/bin/quickstart.sh +++ b/bin/quickstart.sh @@ -1,143 +1,141 @@ #!/bin/bash set -e function die() { echo "$1" exit 1 } rpm -qv docker-compose >/dev/null 2>&1 || \ test ! -z "$(which docker-compose 2>/dev/null)" || \ die "Is docker-compose installed?" test ! -z "$(grep 'systemd.unified_cgroup_hierarchy=0' /proc/cmdline)" || \ die "systemd containers only work with cgroupv1 (use 'grubby --update-kernel=ALL --args=\"systemd.unified_cgroup_hierarchy=0\"' and a reboot to fix)" base_dir=$(dirname $(dirname $0)) # Always reset .env with .env.example cp src/.env.example src/.env if [ -f "src/env.local" ]; then # Ensure there's a line ending echo "" >> src/.env cat src/env.local >> src/.env fi export DOCKER_BUILDKIT=0 docker pull docker.io/kolab/centos7:latest docker-compose down --remove-orphans src/artisan octane:stop >/dev/null 2>&1 || : src/artisan horizon:terminate >/dev/null 2>&1 || : -docker-compose build coturn kolab mariadb meet pdns-sql proxy redis nginx haproxy +docker-compose build coturn kolab mariadb meet pdns-sql proxy redis haproxy bin/regen-certs docker-compose up -d coturn kolab mariadb meet pdns-sql proxy redis haproxy # Workaround until we have docker-compose --wait (https://github.com/docker/compose/pull/8777) function wait_for_container { container_id="$1" container_name="$(docker inspect "${container_id}" --format '{{ .Name }}')" echo "Waiting for container: ${container_name} [${container_id}]" waiting_done="false" while [[ "${waiting_done}" != "true" ]]; do container_state="$(docker inspect "${container_id}" --format '{{ .State.Status }}')" if [[ "${container_state}" == "running" ]]; then health_status="$(docker inspect "${container_id}" --format '{{ .State.Health.Status }}')" echo "${container_name}: container_state=${container_state}, health_status=${health_status}" if [[ ${health_status} == "healthy" ]]; then waiting_done="true" fi else echo "${container_name}: container_state=${container_state}" waiting_done="true" fi sleep 1; done; } # Ensure the containers we depend on are fully started wait_for_container 'kolab' wait_for_container 'kolab-redis' if [ "$1" == "--nodev" ]; then echo "starting everything in containers" docker-compose build swoole docker-compose build webapp - docker-compose up -d webapp nginx + docker-compose up -d webapp proxy wait_for_container 'kolab-webapp' exit 0 fi echo "Starting the development environment" rpm -qv composer >/dev/null 2>&1 || \ test ! -z "$(which composer 2>/dev/null)" || \ die "Is composer installed?" rpm -qv npm >/dev/null 2>&1 || \ test ! -z "$(which npm 2>/dev/null)" || \ die "Is npm installed?" rpm -qv php >/dev/null 2>&1 || \ test ! -z "$(which php 2>/dev/null)" || \ die "Is php installed?" rpm -qv php-ldap >/dev/null 2>&1 || \ test ! -z "$(php --ini | grep ldap)" || \ die "Is php-ldap installed?" rpm -qv php-mysqlnd >/dev/null 2>&1 || \ test ! -z "$(php --ini | grep mysql)" || \ die "Is php-mysqlnd installed?" test ! -z "$(php --modules | grep swoole)" || \ die "Is swoole installed?" pushd ${base_dir}/src/ rm -rf vendor/ composer.lock php -dmemory_limit=-1 $(which composer) install npm install find bootstrap/cache/ -type f ! -name ".gitignore" -delete ./artisan key:generate ./artisan clear-compiled ./artisan cache:clear ./artisan horizon:install if [ ! -f storage/oauth-public.key -o ! -f storage/oauth-private.key ]; then ./artisan passport:keys --force fi cat >> .env << EOF PASSPORT_PRIVATE_KEY="$(cat storage/oauth-private.key)" PASSPORT_PUBLIC_KEY="$(cat storage/oauth-public.key)" EOF if rpm -qv chromium 2>/dev/null; then chver=$(rpmquery --queryformat="%{VERSION}" chromium | awk -F'.' '{print $1}') ./artisan dusk:chrome-driver ${chver} fi if [ ! -f 'resources/countries.php' ]; then ./artisan data:countries fi npm run dev popd -docker-compose up -d nginx - pushd ${base_dir}/src/ rm -rf database/database.sqlite ./artisan db:ping --wait php -dmemory_limit=512M ./artisan migrate:refresh --seed ./artisan data:import || : nohup ./artisan octane:start --host=$(grep OCTANE_HTTP_HOST .env | tail -n1 | sed "s/OCTANE_HTTP_HOST=//") > octane.out & nohup ./artisan horizon > horizon.out & popd diff --git a/docker-compose.yml b/docker-compose.yml index e3bc3240..f4a867c5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,274 +1,246 @@ version: '3' services: coturn: build: context: ./docker/coturn/ container_name: kolab-coturn healthcheck: interval: 10s test: "kill -0 $$(cat /tmp/turnserver.pid)" timeout: 5s retries: 30 environment: - TURN_PUBLIC_IP=${COTURN_PUBLIC_IP} - TURN_LISTEN_PORT=3478 - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} hostname: sturn.mgmt.com image: kolab-coturn network_mode: host restart: on-failure tty: true kolab: build: context: ./docker/kolab/ container_name: kolab privileged: true depends_on: mariadb: condition: service_healthy extra_hosts: - "kolab.mgmt.com:127.0.0.1" environment: - DB_HOST=${DB_HOST} - DB_ROOT_PASSWORD=Welcome2KolabSystems - DB_HKCCP_DATABASE=${DB_DATABASE} - DB_HKCCP_USERNAME=${DB_USERNAME} - DB_HKCCP_PASSWORD=${DB_PASSWORD} - DB_KOLAB_DATABASE=kolab - DB_KOLAB_USERNAME=kolab - DB_KOLAB_PASSWORD=Welcome2KolabSystems - DB_RC_USERNAME=roundcube - DB_RC_PASSWORD=Welcome2KolabSystems - SSL_CERTIFICATE=${KOLAB_SSL_CERTIFICATE:?err} - SSL_CERTIFICATE_FULLCHAIN=${KOLAB_SSL_CERTIFICATE_FULLCHAIN:?err} - SSL_CERTIFICATE_KEY=${KOLAB_SSL_CERTIFICATE_KEY:?err} - IMAP_HOST=127.0.0.1 - IMAP_PORT=11993 - MAIL_HOST=127.0.0.1 - MAIL_PORT=10587 healthcheck: interval: 10s test: test -f /tmp/kolab-init.done timeout: 5s retries: 30 hostname: kolab.mgmt.com image: kolab network_mode: host tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./ext/:/src/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro - ./docker/certs/ca.cert:/etc/pki/tls/certs/ca.cert:ro - ./docker/certs/ca.cert:/etc/pki/ca-trust/source/anchors/ca.cert:ro - ./docker/certs/kolab.hosted.com.cert:/etc/pki/tls/certs/kolab.hosted.com.cert - ./docker/certs/kolab.hosted.com.chain.pem:/etc/pki/tls/certs/kolab.hosted.com.chain.pem - ./docker/certs/kolab.hosted.com.key:/etc/pki/tls/certs/kolab.hosted.com.key - ./docker/certs/kolab.mgmt.com.cert:/etc/pki/tls/certs/kolab.mgmt.com.cert - ./docker/certs/kolab.mgmt.com.key:/etc/pki/tls/certs/kolab.mgmt.com.key - ./docker/kolab/utils:/root/utils:ro - /sys/fs/cgroup:/sys/fs/cgroup:ro mariadb: container_name: kolab-mariadb environment: MYSQL_ROOT_PASSWORD: Welcome2KolabSystems TZ: "+02:00" healthcheck: interval: 10s test: test -e /var/run/mysqld/mysqld.sock timeout: 5s retries: 30 image: mariadb network_mode: host - nginx: - build: - context: ./docker/nginx/ - args: - APP_WEBSITE_DOMAIN: ${APP_WEBSITE_DOMAIN:?err} - SSL_CERTIFICATE: ${NGINX_SSL_CERTIFICATE:?err} - SSL_CERTIFICATE_KEY: ${NGINX_SSL_CERTIFICATE_KEY:?err} - depends_on: - kolab: - condition: service_healthy - healthcheck: - interval: 10s - test: "kill -0 $$(cat /run/nginx.pid)" - timeout: 5s - retries: 30 - container_name: kolab-nginx - hostname: nginx.hosted.com - image: kolab-nginx - network_mode: host - tmpfs: - - /run - - /tmp - - /var/run - - /var/tmp - tty: true - volumes: - - ./docker/certs/:/etc/certs/:ro - - /etc/letsencrypt/:/etc/letsencrypt/:ro haproxy: build: context: ./docker/haproxy/ healthcheck: interval: 10s test: "kill -0 $$(cat /var/run/haproxy.pid)" timeout: 5s retries: 30 container_name: kolab-haproxy hostname: haproxy.hosted.com image: kolab-haproxy network_mode: host tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./docker/certs/:/etc/certs/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro pdns-sql: build: context: ./docker/pdns-sql/ container_name: kolab-pdns-sql depends_on: mariadb: condition: service_healthy healthcheck: interval: 10s test: "systemctl status pdns || exit 1" timeout: 5s retries: 30 hostname: pdns-sql image: apheleia/kolab-pdns-sql network_mode: host tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro proxy: build: context: ./docker/proxy/ args: APP_WEBSITE_DOMAIN: ${APP_WEBSITE_DOMAIN:?err} SSL_CERTIFICATE: ${PROXY_SSL_CERTIFICATE:?err} SSL_CERTIFICATE_KEY: ${PROXY_SSL_CERTIFICATE_KEY:?err} healthcheck: interval: 10s test: "kill -0 $$(cat /run/nginx.pid)" timeout: 5s retries: 30 container_name: kolab-proxy hostname: ${APP_WEBSITE_DOMAIN:?err} image: kolab-proxy network_mode: host tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./docker/certs/:/etc/certs/:ro - /etc/letsencrypt/:/etc/letsencrypt/:ro redis: build: context: ./docker/redis/ healthcheck: interval: 10s test: "redis-cli ping || exit 1" timeout: 5s retries: 30 container_name: kolab-redis hostname: redis image: redis network_mode: host volumes: - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro swoole: build: context: ./docker/swoole/ container_name: kolab-swoole image: apheleia/swoole:4.8.x webapp: build: context: ./docker/webapp/ container_name: kolab-webapp image: kolab-webapp healthcheck: interval: 10s test: "/src/kolabsrc/artisan octane:status || exit 1" timeout: 5s retries: 30 depends_on: kolab: condition: service_healthy network_mode: host volumes: - ./src:/src/kolabsrc.orig:ro tests: build: context: ./docker/tests/ container_name: kolab-tests image: kolab-tests depends_on: kolab: condition: service_healthy network_mode: host volumes: - ./src:/src/kolabsrc.orig:ro worker: build: context: ./docker/worker/ container_name: kolab-worker depends_on: - kolab hostname: worker image: kolab-worker network_mode: host tmpfs: - /run - /tmp - /var/run - /var/tmp tty: true volumes: - ./src:/home/worker/src.orig:ro - /sys/fs/cgroup:/sys/fs/cgroup:ro meet: build: context: ./docker/meet/ healthcheck: interval: 10s test: "curl --insecure -H 'X-AUTH-TOKEN: ${MEET_SERVER_TOKEN}' --fail https://localhost:12443/meetmedia/api/health || exit 1" timeout: 5s retries: 30 environment: - WEBRTC_LISTEN_IP=${MEET_WEBRTC_LISTEN_IP:?err} - PUBLIC_DOMAIN=${MEET_PUBLIC_DOMAIN:?err} - LISTENING_HOST=0.0.0.0 - LISTENING_PORT=12443 - TURN_SERVER=${MEET_TURN_SERVER} - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} - AUTH_TOKEN=${MEET_SERVER_TOKEN:?err} - WEBHOOK_TOKEN=${MEET_WEBHOOK_TOKEN:?err} - WEBHOOK_URL=${APP_PUBLIC_URL:?err}/api/webhooks/meet - SSL_CERT=/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN:?err}.cert - SSL_KEY=/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN:?err}.key network_mode: host container_name: kolab-meet image: kolab-meet volumes: - ./meet/server:/src/meet/:ro - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.cert:/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN}.cert - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.key:/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN}.key diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile deleted file mode 100644 index 42c2f91d..00000000 --- a/docker/nginx/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM fedora:35 - -MAINTAINER Jeroen van Meeuwen - -ENV container docker - -RUN dnf -y install \ - --setopt 'tsflags=nodocs' \ - nginx \ - nginx-mod-mail && \ - dnf clean all - -COPY nginx.conf /etc/nginx/nginx.conf -ARG APP_WEBSITE_DOMAIN -ARG SSL_CERTIFICATE -ARG SSL_CERTIFICATE_KEY -RUN sed -i -r -e "s|APP_WEBSITE_DOMAIN|$APP_WEBSITE_DOMAIN|g" /etc/nginx/nginx.conf -RUN sed -i -r -e "s|SSL_CERTIFICATE_CERT|$SSL_CERTIFICATE|g" /etc/nginx/nginx.conf -RUN sed -i -r -e "s|SSL_CERTIFICATE_KEY|$SSL_CERTIFICATE_KEY|g" /etc/nginx/nginx.conf - -# Forward request logs to Docker log collector -RUN ln -sf /dev/stdout /var/log/nginx/access.log \ - && ln -sf /dev/stderr /var/log/nginx/error.log - -STOPSIGNAL SIGTERM - -CMD ["nginx", "-g", "daemon off;"] - -EXPOSE 110/tcp 143/tcp 993/tcp 995/tcp diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf deleted file mode 100644 index a72a6bc7..00000000 --- a/docker/nginx/nginx.conf +++ /dev/null @@ -1,90 +0,0 @@ -user nginx; -worker_processes auto; -error_log /var/log/nginx/error.log debug; -pid /run/nginx.pid; - -# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. -include /usr/share/nginx/modules/*.conf; - -events { - worker_connections 1024; -} - -mail { - server_name imap.hosted.com; - auth_http 127.0.0.1:8000/api/webhooks/nginx; - auth_http_header Host services.APP_WEBSITE_DOMAIN; - - proxy_pass_error_message on; - - server { - listen 143; - protocol imap; - - proxy on; - starttls on; - - ssl_certificate SSL_CERTIFICATE_CERT; - ssl_certificate_key SSL_CERTIFICATE_KEY; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers HIGH:!aNULL:!MD5; - } - - # Roundcube specific imap endpoint with proxy-protocol enabled - server { - listen 144 proxy_protocol; - protocol imap; - - auth_http 127.0.0.1:8000/api/webhooks/nginx-roundcube; - - proxy on; - starttls on; - - ssl_certificate SSL_CERTIFICATE_CERT; - ssl_certificate_key SSL_CERTIFICATE_KEY; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers HIGH:!aNULL:!MD5; - } - - server { - listen 465 ssl; - protocol smtp; - - proxy on; - - ssl_certificate SSL_CERTIFICATE_CERT; - ssl_certificate_key SSL_CERTIFICATE_KEY; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers HIGH:!aNULL:!MD5; - } - - server { - listen 587; - protocol smtp; - - proxy on; - starttls on; - - ssl_certificate SSL_CERTIFICATE_CERT; - ssl_certificate_key SSL_CERTIFICATE_KEY; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers HIGH:!aNULL:!MD5; - } - - server { - listen 993 ssl; - protocol imap; - - proxy on; - - ssl_certificate SSL_CERTIFICATE_CERT; - ssl_certificate_key SSL_CERTIFICATE_KEY; - - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_ciphers HIGH:!aNULL:!MD5; - } -} diff --git a/docker/proxy/Dockerfile b/docker/proxy/Dockerfile index 64cd0a7d..2a3c8ba9 100644 --- a/docker/proxy/Dockerfile +++ b/docker/proxy/Dockerfile @@ -1,28 +1,29 @@ FROM fedora:35 MAINTAINER Jeroen van Meeuwen ENV container docker RUN dnf -y install \ --setopt 'tsflags=nodocs' \ - nginx && \ + nginx \ + nginx-mod-mail && \ dnf clean all COPY rootfs/ / ARG APP_WEBSITE_DOMAIN ARG SSL_CERTIFICATE ARG SSL_CERTIFICATE_KEY RUN sed -i -r -e "s|APP_WEBSITE_DOMAIN|$APP_WEBSITE_DOMAIN|g" /etc/nginx/nginx.conf RUN sed -i -r -e "s|SSL_CERTIFICATE_CERT|$SSL_CERTIFICATE|g" /etc/nginx/nginx.conf RUN sed -i -r -e "s|SSL_CERTIFICATE_KEY|$SSL_CERTIFICATE_KEY|g" /etc/nginx/nginx.conf # Forward request logs to Docker log collector RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log STOPSIGNAL SIGTERM CMD ["nginx", "-g", "daemon off;"] -EXPOSE 80/tcp 443/tcp +EXPOSE 80/tcp 443/tcp 110/tcp 143/tcp 993/tcp 995/tcp diff --git a/docker/proxy/rootfs/etc/nginx/nginx.conf b/docker/proxy/rootfs/etc/nginx/nginx.conf index cd0b4d32..c961fd59 100644 --- a/docker/proxy/rootfs/etc/nginx/nginx.conf +++ b/docker/proxy/rootfs/etc/nginx/nginx.conf @@ -1,167 +1,247 @@ + # For more information on configuration, see: # * Official English Documentation: http://nginx.org/en/docs/ # * Official Russian Documentation: http://nginx.org/ru/docs/ user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; map $http_upgrade $connection_upgrade { default upgrade; '' close; } # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx_core_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen [::]:443 ssl ipv6only=on; listen 443 ssl; ssl_certificate SSL_CERTIFICATE_CERT; ssl_certificate_key SSL_CERTIFICATE_KEY; server_name APP_WEBSITE_DOMAIN; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_pass http://127.0.0.1:8000; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; # Mostly for files, swoole has a 10MB limit client_max_body_size 11m; } location /meetmedia { proxy_pass https://127.0.0.1:12443; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; } location /meetmedia/api { proxy_pass https://127.0.0.1:12443; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; } location /roundcubemail { proxy_pass http://127.0.0.1:9080; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; } location /kolab-webadmin { proxy_pass http://127.0.0.1:9080; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_no_cache 1; proxy_cache_bypass 1; } location /Microsoft-Server-ActiveSync { auth_request /auth; #auth_request_set $auth_status $upstream_status; proxy_pass http://127.0.0.1:9080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_send_timeout 910s; proxy_read_timeout 910s; fastcgi_send_timeout 910s; fastcgi_read_timeout 910s; } location ~* ^/\\.well-known/(caldav|carddav) { proxy_pass http://127.0.0.1:9080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /iRony { auth_request /auth; #auth_request_set $auth_status $upstream_status; proxy_pass http://127.0.0.1:9080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location = /auth { internal; proxy_pass http://127.0.0.1:8000/api/webhooks/nginx-httpauth; proxy_pass_request_body off; proxy_set_header Host services.APP_WEBSITE_DOMAIN; proxy_set_header Content-Length ""; proxy_set_header X-Original-URI $request_uri; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } } } + +mail { + server_name imap.hosted.com; + auth_http 127.0.0.1:8000/api/webhooks/nginx; + auth_http_header Host services.APP_WEBSITE_DOMAIN; + + proxy_pass_error_message on; + + server { + listen 143; + protocol imap; + + proxy on; + starttls on; + + ssl_certificate SSL_CERTIFICATE_CERT; + ssl_certificate_key SSL_CERTIFICATE_KEY; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + } + + # Roundcube specific imap endpoint with proxy-protocol enabled + server { + listen 144 proxy_protocol; + protocol imap; + + auth_http 127.0.0.1:8000/api/webhooks/nginx-roundcube; + + proxy on; + starttls on; + + ssl_certificate SSL_CERTIFICATE_CERT; + ssl_certificate_key SSL_CERTIFICATE_KEY; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + } + + server { + listen 465 ssl; + protocol smtp; + + proxy on; + + ssl_certificate SSL_CERTIFICATE_CERT; + ssl_certificate_key SSL_CERTIFICATE_KEY; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + } + + server { + listen 587; + protocol smtp; + + proxy on; + starttls on; + + ssl_certificate SSL_CERTIFICATE_CERT; + ssl_certificate_key SSL_CERTIFICATE_KEY; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + } + + server { + listen 993 ssl; + protocol imap; + + proxy on; + + ssl_certificate SSL_CERTIFICATE_CERT; + ssl_certificate_key SSL_CERTIFICATE_KEY; + + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_ciphers HIGH:!aNULL:!MD5; + } +}