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:
@@ -6,6 +6,8 @@ def main():
|
||||
|
||||
if container_name == "sogo-mailcow":
|
||||
from modules.BootstrapSogo import Bootstrap
|
||||
elif container_name == "nginx-mailcow":
|
||||
from modules.BootstrapNginx import Bootstrap
|
||||
else:
|
||||
print(f"No bootstrap handler for container: {container_name}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -347,7 +347,7 @@ class BootstrapBase:
|
||||
if self.mysql_conn.is_connected():
|
||||
print("MySQL is up and ready!")
|
||||
break
|
||||
except Error as e:
|
||||
except mysql.connector.Error as e:
|
||||
print(f"Waiting for MySQL... ({e})")
|
||||
time.sleep(2)
|
||||
|
||||
@@ -390,6 +390,30 @@ class BootstrapBase:
|
||||
print(f"Waiting for schema update... (DB: {current_version}, Expected: {expected_version})")
|
||||
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):
|
||||
"""
|
||||
Fetches the current schema version from the database.
|
||||
|
||||
69
data/Dockerfiles/bootstrap/modules/BootstrapNginx.py
Normal file
69
data/Dockerfiles/bootstrap/modules/BootstrapNginx.py
Normal 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
|
||||
@@ -5,14 +5,20 @@ ENV PIP_BREAK_SYSTEM_PACKAGES=1
|
||||
|
||||
RUN apk add --no-cache nginx \
|
||||
python3 \
|
||||
supervisor \
|
||||
py3-pip && \
|
||||
pip install --upgrade pip && \
|
||||
pip install Jinja2
|
||||
pip install Jinja2 \
|
||||
mysql-connector-python
|
||||
|
||||
RUN mkdir -p /etc/nginx/includes
|
||||
|
||||
COPY ./bootstrap.py /
|
||||
COPY ./docker-entrypoint.sh /
|
||||
COPY data/Dockerfiles/bootstrap /bootstrap
|
||||
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"]
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
RUN chmod +x /docker-entrypoint.sh
|
||||
RUN chmod +x /usr/local/sbin/stop-supervisor.sh
|
||||
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]
|
||||
|
||||
@@ -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()
|
||||
@@ -1,26 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
PHPFPMHOST=${PHPFPMHOST:-"php-fpm-mailcow"}
|
||||
SOGOHOST=${SOGOHOST:-"$IPV4_NETWORK.248"}
|
||||
RSPAMDHOST=${RSPAMDHOST:-"rspamd-mailcow"}
|
||||
python3 -u /bootstrap/main.py
|
||||
BOOTSTRAP_EXIT_CODE=$?
|
||||
|
||||
until ping ${PHPFPMHOST} -c1 > /dev/null; do
|
||||
echo "Waiting for PHP..."
|
||||
sleep 1
|
||||
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
|
||||
if [ $BOOTSTRAP_EXIT_CODE -ne 0 ]; then
|
||||
echo "Bootstrap failed with exit code $BOOTSTRAP_EXIT_CODE. Not starting Nginx."
|
||||
exit $BOOTSTRAP_EXIT_CODE
|
||||
fi
|
||||
|
||||
python3 /bootstrap.py
|
||||
|
||||
exec "$@"
|
||||
echo "Bootstrap succeeded. Starting Nginx..."
|
||||
nginx -g "daemon off;"
|
||||
|
||||
8
data/Dockerfiles/nginx/stop-supervisor.sh
Executable file
8
data/Dockerfiles/nginx/stop-supervisor.sh
Executable 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
|
||||
27
data/Dockerfiles/nginx/supervisord.conf
Normal file
27
data/Dockerfiles/nginx/supervisord.conf
Normal 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
|
||||
@@ -11,7 +11,7 @@ stderr_logfile_maxbytes=0
|
||||
autostart=true
|
||||
priority=1
|
||||
|
||||
[program:bootstrap-sogo]
|
||||
[program:bootstrap]
|
||||
command=/docker-entrypoint.sh
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
|
||||
2
data/conf/nginx/templates/listen_plain.active.j2
Normal file
2
data/conf/nginx/templates/listen_plain.active.j2
Normal file
@@ -0,0 +1,2 @@
|
||||
listen {{ HTTP_PORT }};
|
||||
listen [::]:{{ HTTP_PORT }};
|
||||
2
data/conf/nginx/templates/listen_ssl.active.j2
Normal file
2
data/conf/nginx/templates/listen_ssl.active.j2
Normal file
@@ -0,0 +1,2 @@
|
||||
listen {{ HTTPS_PORT }} ssl http2;
|
||||
listen [::]:{{ HTTPS_PORT }} ssl http2;
|
||||
@@ -41,7 +41,7 @@ http {
|
||||
https https;
|
||||
}
|
||||
|
||||
{% if HTTP_REDIRECT %}
|
||||
{% if HTTP_REDIRECT|lower in ["y", "yes"] %}
|
||||
# HTTP to HTTPS redirect
|
||||
server {
|
||||
root /web;
|
||||
@@ -65,16 +65,16 @@ http {
|
||||
server {
|
||||
listen 127.0.0.1:65510; # sogo-auth verify internal
|
||||
|
||||
{% if not HTTP_REDIRECT %}
|
||||
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
|
||||
{% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
|
||||
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%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 HTTP_REDIRECT %}
|
||||
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
|
||||
{% if not DISABLE_IPv6|lower in ["y", "yes"] %}
|
||||
{% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
|
||||
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%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%}
|
||||
|
||||
http2 on;
|
||||
@@ -92,16 +92,16 @@ http {
|
||||
server {
|
||||
listen 127.0.0.1:65510; # sogo-auth verify internal
|
||||
|
||||
{% if not HTTP_REDIRECT %}
|
||||
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
|
||||
{% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
|
||||
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%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 HTTP_REDIRECT %}
|
||||
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
|
||||
{% if not DISABLE_IPv6|lower in ["y", "yes"] %}
|
||||
{% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
|
||||
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%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%}
|
||||
|
||||
http2 on;
|
||||
@@ -118,7 +118,7 @@ http {
|
||||
# rspamd dynmaps:
|
||||
server {
|
||||
listen 8081;
|
||||
{% if not DISABLE_IPv6 %}
|
||||
{% if not DISABLE_IPv6|lower in ["y", "yes"] %}
|
||||
listen [::]:8081;
|
||||
{%endif%}
|
||||
index index.php index.html;
|
||||
@@ -184,18 +184,18 @@ http {
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
{% for cert in valid_cert_dirs %}
|
||||
{% for cert in VALID_CERT_DIRS %}
|
||||
server {
|
||||
{% if not HTTP_REDIRECT %}
|
||||
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
|
||||
{% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
|
||||
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%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 HTTP_REDIRECT %}
|
||||
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
|
||||
{% if not DISABLE_IPv6|lower in ["y", "yes"] %}
|
||||
{% if not HTTP_REDIRECT|lower in ["y", "yes"] %}
|
||||
listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %} proxy_protocol{%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%}
|
||||
|
||||
http2 on;
|
||||
|
||||
1
data/conf/nginx/templates/server_name.active.j2
Normal file
1
data/conf/nginx/templates/server_name.active.j2
Normal file
@@ -0,0 +1 @@
|
||||
server_name {{ MAILCOW_HOSTNAME }} autodiscover.* autoconfig.* {{ ADDITIONAL_SERVER_NAMES | join(' ') }};
|
||||
@@ -55,7 +55,7 @@ set_real_ip_from fc00::/7;
|
||||
{% for TRUSTED_PROXY in TRUSTED_PROXIES %}
|
||||
set_real_ip_from {{ TRUSTED_PROXY }};
|
||||
{% endfor %}
|
||||
{% if not NGINX_USE_PROXY_PROTOCOL %}
|
||||
{% if not NGINX_USE_PROXY_PROTOCOL|lower in ["y", "yes"] %}
|
||||
real_ip_header X-Forwarded-For;
|
||||
{% else %}
|
||||
real_ip_header proxy_protocol;
|
||||
@@ -137,28 +137,28 @@ location ~ /(?:m|M)ail/(?:c|C)onfig-v1.1.xml {
|
||||
try_files /autoconfig.php =404;
|
||||
}
|
||||
|
||||
{% if not SKIP_RSPAMD %}
|
||||
{% if not SKIP_RSPAMD|lower in ["y", "yes"] %}
|
||||
location /rspamd/ {
|
||||
location /rspamd/auth {
|
||||
# proxy_pass is not inherited
|
||||
proxy_pass http://{{ RSPAMDHOST }}:11334/auth;
|
||||
proxy_intercept_errors on;
|
||||
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-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% 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|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
|
||||
proxy_redirect off;
|
||||
error_page 401 /_rspamderror.php;
|
||||
}
|
||||
|
||||
proxy_pass http://{{ RSPAMDHOST }}:11334/;
|
||||
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-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% 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|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
|
||||
proxy_redirect off;
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
{% if not SKIP_SOGO %}
|
||||
{% if not SKIP_SOGO|lower in ["y", "yes"] %}
|
||||
location ^~ /principals {
|
||||
return 301 /SOGo/dav;
|
||||
}
|
||||
@@ -184,8 +184,8 @@ location ^~ /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-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% 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|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
|
||||
proxy_connect_timeout 75;
|
||||
proxy_send_timeout 3600;
|
||||
proxy_read_timeout 3600;
|
||||
@@ -209,8 +209,8 @@ location ^~ /SOGo {
|
||||
|
||||
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-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% 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|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
|
||||
proxy_set_header x-webobjects-remote-host $remote_addr;
|
||||
@@ -231,8 +231,8 @@ location ^~ /SOGo {
|
||||
|
||||
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-Real-IP {% if not NGINX_USE_PROXY_PROTOCOL %}$remote_addr{% 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|lower in ["y", "yes"] %}$remote_addr{% else %}$proxy_protocol_addr{%endif%};
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header x-webobjects-server-protocol HTTP/1.0;
|
||||
proxy_set_header x-webobjects-remote-host $remote_addr;
|
||||
|
||||
@@ -200,8 +200,9 @@ services:
|
||||
- phpfpm
|
||||
|
||||
sogo-mailcow:
|
||||
image: ghcr.io/mailcow/sogo:1.133
|
||||
image: ghcr.io/mailcow/sogo:nightly-16052025
|
||||
environment:
|
||||
- CONTAINER_NAME=sogo-mailcow
|
||||
- DBNAME=${DBNAME}
|
||||
- DBUSER=${DBUSER}
|
||||
- DBPASS=${DBPASS}
|
||||
@@ -394,10 +395,14 @@ services:
|
||||
- php-fpm-mailcow
|
||||
- sogo-mailcow
|
||||
- rspamd-mailcow
|
||||
image: ghcr.io/mailcow/nginx:1.03
|
||||
image: ghcr.io/mailcow/nginx:nightly-19052025
|
||||
dns:
|
||||
- ${IPV4_NETWORK:-172.22.1}.254
|
||||
environment:
|
||||
- CONTAINER_NAME=nginx-mailcow
|
||||
- DBNAME=${DBNAME}
|
||||
- DBUSER=${DBUSER}
|
||||
- DBPASS=${DBPASS}
|
||||
- HTTPS_PORT=${HTTPS_PORT:-443}
|
||||
- HTTP_PORT=${HTTP_PORT:-80}
|
||||
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
|
||||
@@ -407,10 +412,10 @@ services:
|
||||
- SKIP_RSPAMD=${SKIP_RSPAMD:-n}
|
||||
- DISABLE_IPv6=${DISABLE_IPv6:-n}
|
||||
- HTTP_REDIRECT=${HTTP_REDIRECT:-n}
|
||||
- PHPFPMHOST=${PHPFPMHOST:-}
|
||||
- SOGOHOST=${SOGOHOST:-}
|
||||
- RSPAMDHOST=${RSPAMDHOST:-}
|
||||
- REDISHOST=${REDISHOST:-}
|
||||
- PHPFPMHOST=${PHPFPMHOST:-php-fpm-mailcow}
|
||||
- RSPAMDHOST=${RSPAMDHOST:-rspamd-mailcow}
|
||||
- SOGOHOST=${SOGOHOST:-${IPV4_NETWORK:-172.22.1}.248}
|
||||
- REDISHOST=${REDISHOST:-redis-mailcow}
|
||||
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
|
||||
- NGINX_USE_PROXY_PROTOCOL=${NGINX_USE_PROXY_PROTOCOL:-n}
|
||||
- TRUSTED_PROXIES=${TRUSTED_PROXIES:-}
|
||||
@@ -424,6 +429,7 @@ services:
|
||||
- ./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/sessions.inc.php:/mailcowauth/sessions.inc.php:z
|
||||
- mysql-socket-vol-1:/var/run/mysqld/
|
||||
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
|
||||
ports:
|
||||
- "${HTTPS_BIND:-}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
|
||||
|
||||
Reference in New Issue
Block a user