1
0
mirror of https://github.com/mailcow/mailcow-dockerized.git synced 2025-12-19 12:51:29 +00:00

[Nginx] use python bootstrapper to start NGINX container

This commit is contained in:
FreddleSpl0it
2025-05-19 09:45:00 +02:00
parent 1d482ed425
commit cde2ba4851
15 changed files with 204 additions and 171 deletions

View File

@@ -6,6 +6,8 @@ def main():
if container_name == "sogo-mailcow": if container_name == "sogo-mailcow":
from modules.BootstrapSogo import Bootstrap from modules.BootstrapSogo import Bootstrap
elif container_name == "nginx-mailcow":
from modules.BootstrapNginx import Bootstrap
else: else:
print(f"No bootstrap handler for container: {container_name}", file=sys.stderr) print(f"No bootstrap handler for container: {container_name}", file=sys.stderr)
sys.exit(1) sys.exit(1)

View File

@@ -347,7 +347,7 @@ class BootstrapBase:
if self.mysql_conn.is_connected(): if self.mysql_conn.is_connected():
print("MySQL is up and ready!") print("MySQL is up and ready!")
break break
except Error as e: except mysql.connector.Error as e:
print(f"Waiting for MySQL... ({e})") print(f"Waiting for MySQL... ({e})")
time.sleep(2) time.sleep(2)
@@ -390,6 +390,30 @@ class BootstrapBase:
print(f"Waiting for schema update... (DB: {current_version}, Expected: {expected_version})") print(f"Waiting for schema update... (DB: {current_version}, Expected: {expected_version})")
time.sleep(check_interval) time.sleep(check_interval)
def wait_for_host(self, host, retry_interval=1.0, count=1):
"""
Waits for a host to respond to ICMP ping.
Args:
host (str): Hostname or IP to ping.
retry_interval (float): Seconds to wait between pings.
count (int): Number of ping packets to send per check (default 1).
"""
while True:
try:
result = subprocess.run(
["ping", "-c", str(count), host],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL
)
if result.returncode == 0:
print(f"{host} is reachable via ping.")
break
except Exception:
pass
print(f"Waiting for {host}...")
time.sleep(retry_interval)
def _get_current_db_version(self): def _get_current_db_version(self):
""" """
Fetches the current schema version from the database. Fetches the current schema version from the database.

View File

@@ -0,0 +1,69 @@
from jinja2 import Environment, FileSystemLoader
from modules.BootstrapBase import BootstrapBase
from pathlib import Path
import os
import sys
import time
class Bootstrap(BootstrapBase):
def bootstrap(self):
# Connect to MySQL
self.connect_mysql()
# wait for Hosts
php_service = os.getenv("PHPFPMHOST") or "php-fpm-mailcow"
rspamd_service = os.getenv("RSPAMDHOST") or "rspamd-mailcow"
sogo_service = os.getenv("SOGOHOST") or os.getenv("IPV4_NETWORK", "172.22.1") + ".248"
self.wait_for_host(php_service)
if not self.isYes(os.getenv("SKIP_RSPAMD", False)):
self.wait_for_host(rspamd_service)
if not self.isYes(os.getenv("SKIP_SOGO", False)):
self.wait_for_host(sogo_service)
# Setup Jinja2 Environment and load vars
self.env = Environment(
loader=FileSystemLoader('./etc/nginx/conf.d/templates'),
keep_trailing_newline=True,
lstrip_blocks=False,
trim_blocks=False
)
extra_vars = {
"VALID_CERT_DIRS": self.get_valid_cert_dirs(),
'TRUSTED_PROXIES': [item.strip() for item in os.getenv("TRUSTED_PROXIES", "").split(",") if item.strip()],
'ADDITIONAL_SERVER_NAMES': [item.strip() for item in os.getenv("ADDITIONAL_SERVER_NAMES", "").split(",") if item.strip()],
}
self.env_vars = self.prepare_template_vars('/overwrites.json', extra_vars)
print("Set Timezone")
self.set_timezone()
print("Render config")
self.render_config("nginx.conf.j2", "/etc/nginx/nginx.conf")
self.render_config("sites-default.conf.j2", "/etc/nginx/includes/sites-default.conf")
self.render_config("server_name.active.j2", "/etc/nginx/conf.d/server_name.active")
self.render_config("listen_plain.active.j2", "/etc/nginx/conf.d/listen_plain.active")
self.render_config("listen_ssl.active.j2", "/etc/nginx/conf.d/listen_ssl.active")
def get_valid_cert_dirs(self):
ssl_dir = '/etc/ssl/mail/'
valid_cert_dirs = []
for d in os.listdir(ssl_dir):
full_path = os.path.join(ssl_dir, d)
if not os.path.isdir(full_path):
continue
cert_path = os.path.join(full_path, 'cert.pem')
key_path = os.path.join(full_path, 'key.pem')
domains_path = os.path.join(full_path, 'domains')
if os.path.isfile(cert_path) and os.path.isfile(key_path) and os.path.isfile(domains_path):
with open(domains_path, 'r') as file:
domains = file.read().strip()
domains_list = domains.split()
if domains_list and os.getenv("MAILCOW_HOSTNAME", "") not in domains_list:
valid_cert_dirs.append({
'cert_path': full_path + '/',
'domains': domains
})
return valid_cert_dirs

View File

@@ -5,14 +5,20 @@ ENV PIP_BREAK_SYSTEM_PACKAGES=1
RUN apk add --no-cache nginx \ RUN apk add --no-cache nginx \
python3 \ python3 \
supervisor \
py3-pip && \ py3-pip && \
pip install --upgrade pip && \ pip install --upgrade pip && \
pip install Jinja2 pip install Jinja2 \
mysql-connector-python
RUN mkdir -p /etc/nginx/includes RUN mkdir -p /etc/nginx/includes
COPY ./bootstrap.py / COPY data/Dockerfiles/bootstrap /bootstrap
COPY ./docker-entrypoint.sh / COPY data/Dockerfiles/nginx/docker-entrypoint.sh /
COPY data/Dockerfiles/nginx/supervisord.conf /etc/supervisor/supervisord.conf
COPY data/Dockerfiles/nginx/stop-supervisor.sh /usr/local/sbin/stop-supervisor.sh
ENTRYPOINT ["/docker-entrypoint.sh"] RUN chmod +x /docker-entrypoint.sh
CMD ["nginx", "-g", "daemon off;"] RUN chmod +x /usr/local/sbin/stop-supervisor.sh
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]

View File

@@ -1,100 +0,0 @@
import os
import subprocess
from jinja2 import Environment, FileSystemLoader
def includes_conf(env, template_vars):
server_name = "server_name.active"
listen_plain = "listen_plain.active"
listen_ssl = "listen_ssl.active"
server_name_config = f"server_name {template_vars['MAILCOW_HOSTNAME']} autodiscover.* autoconfig.* {' '.join(template_vars['ADDITIONAL_SERVER_NAMES'])};"
listen_plain_config = f"listen {template_vars['HTTP_PORT']};"
listen_ssl_config = f"listen {template_vars['HTTPS_PORT']};"
if not template_vars['DISABLE_IPv6']:
listen_plain_config += f"\nlisten [::]:{template_vars['HTTP_PORT']};"
listen_ssl_config += f"\nlisten [::]:{template_vars['HTTPS_PORT']} ssl;"
listen_ssl_config += "\nhttp2 on;"
with open(f"/etc/nginx/conf.d/{server_name}", "w") as f:
f.write(server_name_config)
with open(f"/etc/nginx/conf.d/{listen_plain}", "w") as f:
f.write(listen_plain_config)
with open(f"/etc/nginx/conf.d/{listen_ssl}", "w") as f:
f.write(listen_ssl_config)
def sites_default_conf(env, template_vars):
config_name = "sites-default.conf"
template = env.get_template(f"{config_name}.j2")
config = template.render(template_vars)
with open(f"/etc/nginx/includes/{config_name}", "w") as f:
f.write(config)
def nginx_conf(env, template_vars):
config_name = "nginx.conf"
template = env.get_template(f"{config_name}.j2")
config = template.render(template_vars)
with open(f"/etc/nginx/{config_name}", "w") as f:
f.write(config)
def prepare_template_vars():
ipv4_network = os.getenv("IPV4_NETWORK", "172.22.1")
additional_server_names = os.getenv("ADDITIONAL_SERVER_NAMES", "")
trusted_proxies = os.getenv("TRUSTED_PROXIES", "")
template_vars = {
'IPV4_NETWORK': ipv4_network,
'TRUSTED_PROXIES': [item.strip() for item in trusted_proxies.split(",") if item.strip()],
'SKIP_RSPAMD': os.getenv("SKIP_RSPAMD", "n").lower() in ("y", "yes"),
'SKIP_SOGO': os.getenv("SKIP_SOGO", "n").lower() in ("y", "yes"),
'NGINX_USE_PROXY_PROTOCOL': os.getenv("NGINX_USE_PROXY_PROTOCOL", "n").lower() in ("y", "yes"),
'MAILCOW_HOSTNAME': os.getenv("MAILCOW_HOSTNAME", ""),
'ADDITIONAL_SERVER_NAMES': [item.strip() for item in additional_server_names.split(",") if item.strip()],
'HTTP_PORT': os.getenv("HTTP_PORT", "80"),
'HTTPS_PORT': os.getenv("HTTPS_PORT", "443"),
'SOGOHOST': os.getenv("SOGOHOST", ipv4_network + ".248"),
'RSPAMDHOST': os.getenv("RSPAMDHOST", "rspamd-mailcow"),
'PHPFPMHOST': os.getenv("PHPFPMHOST", "php-fpm-mailcow"),
'DISABLE_IPv6': os.getenv("DISABLE_IPv6", "n").lower() in ("y", "yes"),
'HTTP_REDIRECT': os.getenv("HTTP_REDIRECT", "n").lower() in ("y", "yes"),
}
ssl_dir = '/etc/ssl/mail/'
template_vars['valid_cert_dirs'] = []
for d in os.listdir(ssl_dir):
full_path = os.path.join(ssl_dir, d)
if not os.path.isdir(full_path):
continue
cert_path = os.path.join(full_path, 'cert.pem')
key_path = os.path.join(full_path, 'key.pem')
domains_path = os.path.join(full_path, 'domains')
if os.path.isfile(cert_path) and os.path.isfile(key_path) and os.path.isfile(domains_path):
with open(domains_path, 'r') as file:
domains = file.read().strip()
domains_list = domains.split()
if domains_list and template_vars["MAILCOW_HOSTNAME"] not in domains_list:
template_vars['valid_cert_dirs'].append({
'cert_path': full_path + '/',
'domains': domains
})
return template_vars
def main():
env = Environment(loader=FileSystemLoader('./etc/nginx/conf.d/templates'))
# Render config
print("Render config")
template_vars = prepare_template_vars()
sites_default_conf(env, template_vars)
nginx_conf(env, template_vars)
includes_conf(env, template_vars)
if __name__ == "__main__":
main()

View File

@@ -1,26 +1,12 @@
#!/bin/sh #!/bin/sh
PHPFPMHOST=${PHPFPMHOST:-"php-fpm-mailcow"} python3 -u /bootstrap/main.py
SOGOHOST=${SOGOHOST:-"$IPV4_NETWORK.248"} BOOTSTRAP_EXIT_CODE=$?
RSPAMDHOST=${RSPAMDHOST:-"rspamd-mailcow"}
until ping ${PHPFPMHOST} -c1 > /dev/null; do if [ $BOOTSTRAP_EXIT_CODE -ne 0 ]; then
echo "Waiting for PHP..." echo "Bootstrap failed with exit code $BOOTSTRAP_EXIT_CODE. Not starting Nginx."
sleep 1 exit $BOOTSTRAP_EXIT_CODE
done
if ! printf "%s\n" "${SKIP_SOGO}" | grep -E '^([yY][eE][sS]|[yY])+$' >/dev/null; then
until ping ${SOGOHOST} -c1 > /dev/null; do
echo "Waiting for SOGo..."
sleep 1
done
fi
if ! printf "%s\n" "${SKIP_RSPAMD}" | grep -E '^([yY][eE][sS]|[yY])+$' >/dev/null; then
until ping ${RSPAMDHOST} -c1 > /dev/null; do
echo "Waiting for Rspamd..."
sleep 1
done
fi fi
python3 /bootstrap.py echo "Bootstrap succeeded. Starting Nginx..."
nginx -g "daemon off;"
exec "$@"

View File

@@ -0,0 +1,8 @@
#!/bin/bash
printf "READY\n";
while read line; do
echo "Processing Event: $line" >&2;
kill -3 $(cat "/var/run/supervisord.pid")
done < /dev/stdin

View File

@@ -0,0 +1,27 @@
[supervisord]
nodaemon=true
user=root
[program:syslog-ng]
command=/usr/sbin/syslog-ng --foreground --no-caps
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
autostart=true
priority=1
[program:bootstrap]
command=/docker-entrypoint.sh
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=2
startretries=10
autorestart=true
stopwaitsecs=120
[eventlistener:processes]
command=/usr/local/sbin/stop-supervisor.sh
events=PROCESS_STATE_STOPPED, PROCESS_STATE_EXITED, PROCESS_STATE_FATAL

View File

@@ -11,7 +11,7 @@ stderr_logfile_maxbytes=0
autostart=true autostart=true
priority=1 priority=1
[program:bootstrap-sogo] [program:bootstrap]
command=/docker-entrypoint.sh command=/docker-entrypoint.sh
stdout_logfile=/dev/stdout stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0 stdout_logfile_maxbytes=0

View File

@@ -0,0 +1,2 @@
listen {{ HTTP_PORT }};
listen [::]:{{ HTTP_PORT }};

View File

@@ -0,0 +1,2 @@
listen {{ HTTPS_PORT }} ssl http2;
listen [::]:{{ HTTPS_PORT }} ssl http2;

View File

@@ -41,7 +41,7 @@ http {
https https; https https;
} }
{% if HTTP_REDIRECT %} {% if HTTP_REDIRECT|lower in ["y", "yes"] %}
# HTTP to HTTPS redirect # HTTP to HTTPS redirect
server { server {
root /web; root /web;
@@ -65,16 +65,16 @@ http {
server { server {
listen 127.0.0.1:65510; # sogo-auth verify internal listen 127.0.0.1:65510; # sogo-auth verify internal
{% if not HTTP_REDIRECT %} {% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%}; listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%};
{%endif%} {%endif%}
listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl; listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%} ssl;
{% if not DISABLE_IPv6 %} {% if not DISABLE_IPv6|lower in ["y", "yes"] %}
{% if not HTTP_REDIRECT %} {% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%}; listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%};
{%endif%} {%endif%}
listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl; listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%} ssl;
{%endif%} {%endif%}
http2 on; http2 on;
@@ -92,16 +92,16 @@ http {
server { server {
listen 127.0.0.1:65510; # sogo-auth verify internal listen 127.0.0.1:65510; # sogo-auth verify internal
{% if not HTTP_REDIRECT %} {% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%}; listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%};
{%endif%} {%endif%}
listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl; listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%} ssl;
{% if not DISABLE_IPv6 %} {% if not DISABLE_IPv6|lower in ["y", "yes"] %}
{% if not HTTP_REDIRECT %} {% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%}; listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%};
{%endif%} {%endif%}
listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl; listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%} ssl;
{%endif%} {%endif%}
http2 on; http2 on;
@@ -118,7 +118,7 @@ http {
# rspamd dynmaps: # rspamd dynmaps:
server { server {
listen 8081; listen 8081;
{% if not DISABLE_IPv6 %} {% if not DISABLE_IPv6|lower in ["y", "yes"] %}
listen [::]:8081; listen [::]:8081;
{%endif%} {%endif%}
index index.php index.html; index index.php index.html;
@@ -184,18 +184,18 @@ http {
include /etc/nginx/conf.d/*.conf; include /etc/nginx/conf.d/*.conf;
{% for cert in valid_cert_dirs %} {% for cert in VALID_CERT_DIRS %}
server { server {
{% if not HTTP_REDIRECT %} {% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%}; listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%};
{%endif%} {%endif%}
listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl; listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%} ssl;
{% if not DISABLE_IPv6 %} {% if not DISABLE_IPv6|lower in ["y", "yes"] %}
{% if not HTTP_REDIRECT %} {% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%}; listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%};
{%endif%} {%endif%}
listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl; listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%endif%} ssl;
{%endif%} {%endif%}
http2 on; http2 on;

View File

@@ -0,0 +1 @@
server_name {{ MAILCOW_HOSTNAME }} autodiscover.* autoconfig.* {{ ADDITIONAL_SERVER_NAMES | join(' ') }};

View File

@@ -55,7 +55,7 @@ set_real_ip_from fc00::/7;
{% for TRUSTED_PROXY in TRUSTED_PROXIES %} {% for TRUSTED_PROXY in TRUSTED_PROXIES %}
set_real_ip_from {{ TRUSTED_PROXY }}; set_real_ip_from {{ TRUSTED_PROXY }};
{% endfor %} {% endfor %}
{% if not NGINX_USE_PROXY_PROTOCOL %} {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}
real_ip_header X-Forwarded-For; real_ip_header X-Forwarded-For;
{% else %} {% else %}
real_ip_header proxy_protocol; real_ip_header proxy_protocol;
@@ -137,28 +137,28 @@ location ~ /(?:m|M)ail/(?:c|C)onfig-v1.1.xml {
try_files /autoconfig.php =404; try_files /autoconfig.php =404;
} }
{% if not SKIP_RSPAMD %} {% if not SKIP_RSPAMD|lower in ["y", "yes"] %}
location /rspamd/ { location /rspamd/ {
location /rspamd/auth { location /rspamd/auth {
# proxy_pass is not inherited # proxy_pass is not inherited
proxy_pass http://{{ RSPAMDHOST }}:11334/auth; proxy_pass http://{{ RSPAMDHOST }}:11334/auth;
proxy_intercept_errors on; proxy_intercept_errors on;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_redirect off; proxy_redirect off;
error_page 401 /_rspamderror.php; error_page 401 /_rspamderror.php;
} }
proxy_pass http://{{ RSPAMDHOST }}:11334/; proxy_pass http://{{ RSPAMDHOST }}:11334/;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_redirect off; proxy_redirect off;
} }
{% endif %} {% endif %}
{% if not SKIP_SOGO %} {% if not SKIP_SOGO|lower in ["y", "yes"] %}
location ^~ /principals { location ^~ /principals {
return 301 /SOGo/dav; return 301 /SOGo/dav;
} }
@@ -184,8 +184,8 @@ location ^~ /Microsoft-Server-ActiveSync {
proxy_pass http://{{ SOGOHOST }}:20000/SOGo/Microsoft-Server-ActiveSync; proxy_pass http://{{ SOGOHOST }}:20000/SOGo/Microsoft-Server-ActiveSync;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_connect_timeout 75; proxy_connect_timeout 75;
proxy_send_timeout 3600; proxy_send_timeout 3600;
proxy_read_timeout 3600; proxy_read_timeout 3600;
@@ -209,8 +209,8 @@ location ^~ /SOGo {
proxy_pass http://{{ SOGOHOST }}:20000; proxy_pass http://{{ SOGOHOST }}:20000;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0; proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host $remote_addr; proxy_set_header x-webobjects-remote-host $remote_addr;
@@ -231,8 +231,8 @@ location ^~ /SOGo {
proxy_pass http://{{ SOGOHOST }}:20000; proxy_pass http://{{ SOGOHOST }}:20000;
proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Forwarded-For {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$proxy_add_x_forwarded_for{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% else %}$proxy_protocol_addr{%endif%}; proxy_set_header X-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header x-webobjects-server-protocol HTTP/1.0; proxy_set_header x-webobjects-server-protocol HTTP/1.0;
proxy_set_header x-webobjects-remote-host $remote_addr; proxy_set_header x-webobjects-remote-host $remote_addr;

View File

@@ -200,8 +200,9 @@ services:
- phpfpm - phpfpm
sogo-mailcow: sogo-mailcow:
image: ghcr.io/mailcow/sogo:1.133 image: ghcr.io/mailcow/sogo:nightly-16052025
environment: environment:
- CONTAINER_NAME=sogo-mailcow
- DBNAME=${DBNAME} - DBNAME=${DBNAME}
- DBUSER=${DBUSER} - DBUSER=${DBUSER}
- DBPASS=${DBPASS} - DBPASS=${DBPASS}
@@ -394,10 +395,14 @@ services:
- php-fpm-mailcow - php-fpm-mailcow
- sogo-mailcow - sogo-mailcow
- rspamd-mailcow - rspamd-mailcow
image: ghcr.io/mailcow/nginx:1.03 image: ghcr.io/mailcow/nginx:nightly-19052025
dns: dns:
- ${IPV4_NETWORK:-172.22.1}.254 - ${IPV4_NETWORK:-172.22.1}.254
environment: environment:
- CONTAINER_NAME=nginx-mailcow
- DBNAME=${DBNAME}
- DBUSER=${DBUSER}
- DBPASS=${DBPASS}
- HTTPS_PORT=${HTTPS_PORT:-443} - HTTPS_PORT=${HTTPS_PORT:-443}
- HTTP_PORT=${HTTP_PORT:-80} - HTTP_PORT=${HTTP_PORT:-80}
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME} - MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
@@ -407,10 +412,10 @@ services:
- SKIP_RSPAMD=${SKIP_RSPAMD:-n} - SKIP_RSPAMD=${SKIP_RSPAMD:-n}
- DISABLE_IPv6=${DISABLE_IPv6:-n} - DISABLE_IPv6=${DISABLE_IPv6:-n}
- HTTP_REDIRECT=${HTTP_REDIRECT:-n} - HTTP_REDIRECT=${HTTP_REDIRECT:-n}
- PHPFPMHOST=${PHPFPMHOST:-} - PHPFPMHOST=${PHPFPMHOST:-php-fpm-mailcow}
- SOGOHOST=${SOGOHOST:-} - RSPAMDHOST=${RSPAMDHOST:-rspamd-mailcow}
- RSPAMDHOST=${RSPAMDHOST:-} - SOGOHOST=${SOGOHOST:-${IPV4_NETWORK:-172.22.1}.248}
- REDISHOST=${REDISHOST:-} - REDISHOST=${REDISHOST:-redis-mailcow}
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1} - IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
- NGINX_USE_PROXY_PROTOCOL=${NGINX_USE_PROXY_PROTOCOL:-n} - NGINX_USE_PROXY_PROTOCOL=${NGINX_USE_PROXY_PROTOCOL:-n}
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-} - TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
@@ -424,6 +429,7 @@ services:
- ./data/web/inc/functions.inc.php:/mailcowauth/functions.inc.php:z - ./data/web/inc/functions.inc.php:/mailcowauth/functions.inc.php:z
- ./data/web/inc/functions.auth.inc.php:/mailcowauth/functions.auth.inc.php:z - ./data/web/inc/functions.auth.inc.php:/mailcowauth/functions.auth.inc.php:z
- ./data/web/inc/sessions.inc.php:/mailcowauth/sessions.inc.php:z - ./data/web/inc/sessions.inc.php:/mailcowauth/sessions.inc.php:z
- mysql-socket-vol-1:/var/run/mysqld/
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/ - sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
ports: ports:
- "${HTTPS_BIND:-}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}" - "${HTTPS_BIND:-}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"