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":
|
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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
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 \
|
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"]
|
||||||
|
|||||||
@@ -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
|
#!/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 "$@"
|
|
||||||
|
|||||||
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
|
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
|
||||||
|
|||||||
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;
|
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;
|
||||||
|
|||||||
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 %}
|
{% 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;
|
||||||
|
|||||||
@@ -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}"
|
||||||
|
|||||||
Reference in New Issue
Block a user