1
0
mirror of https://github.com/mailcow/mailcow-dockerized.git synced 2025-12-24 07:11:32 +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":
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)

View File

@@ -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.

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