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

[Mysql] use python bootstrapper to start MYSQL container

This commit is contained in:
FreddleSpl0it
2025-05-22 07:54:29 +02:00
parent 55d90afee4
commit faf8fa8c2c
8 changed files with 138 additions and 5 deletions

1
.gitignore vendored
View File

@@ -53,6 +53,7 @@ data/conf/sogo/cron.creds
data/conf/sogo/custom-fulllogo.svg data/conf/sogo/custom-fulllogo.svg
data/conf/sogo/custom-shortlogo.svg data/conf/sogo/custom-shortlogo.svg
data/conf/sogo/custom-fulllogo.png data/conf/sogo/custom-fulllogo.png
data/conf/mysql/my.cnf
data/gitea/ data/gitea/
data/gogs/ data/gogs/
data/hooks/dovecot/* data/hooks/dovecot/*

View File

@@ -23,6 +23,8 @@ def main():
from modules.BootstrapRspamd import Bootstrap from modules.BootstrapRspamd import Bootstrap
elif container_name == "clamd-mailcow": elif container_name == "clamd-mailcow":
from modules.BootstrapClamd import Bootstrap from modules.BootstrapClamd import Bootstrap
elif container_name == "mysql-mailcow":
from modules.BootstrapMysql 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)
@@ -31,9 +33,9 @@ def main():
container=container_name, container=container_name,
db_config={ db_config={
"host": "localhost", "host": "localhost",
"user": os.getenv("DBUSER"), "user": os.getenv("DBUSER") or os.getenv("MYSQL_USER"),
"password": os.getenv("DBPASS"), "password": os.getenv("DBPASS") or os.getenv("MYSQL_PASSWORD"),
"database": os.getenv("DBNAME"), "database": os.getenv("DBNAME") or os.getenv("MYSQL_DATABASE"),
"unix_socket": "/var/run/mysqld/mysqld.sock", "unix_socket": "/var/run/mysqld/mysqld.sock",
'connection_timeout': 2 'connection_timeout': 2
}, },

View File

@@ -0,0 +1,80 @@
from jinja2 import Environment, FileSystemLoader
from modules.BootstrapBase import BootstrapBase
from pathlib import Path
import os
import sys
import time
import platform
import subprocess
class Bootstrap(BootstrapBase):
def bootstrap(self):
self.upgrade_mysql()
# Setup Jinja2 Environment and load vars
self.env = Environment(
loader=FileSystemLoader('./etc/mysql/conf.d/config_templates'),
keep_trailing_newline=True,
lstrip_blocks=True,
trim_blocks=True
)
extra_vars = {
}
self.env_vars = self.prepare_template_vars('/overwrites.json', extra_vars)
print("Set Timezone")
self.set_timezone()
print("Render config")
self.render_config("my.cnf.j2", "/etc/mysql/conf.d/my.cnf")
def upgrade_mysql(self, max_retries=5, wait_interval=3):
"""
Runs mysql_upgrade in a controlled way using run_command.
Starts mysqld in background, upgrades, shuts down, then restarts in foreground.
"""
dbuser = "root"
dbpass = os.getenv("MYSQL_ROOT_PASSWORD", "")
socket = "/var/run/mysqld/mysqld.sock"
print("Starting temporary mysqld for upgrade...")
temp_proc = subprocess.Popen([
"mysqld",
"--user=mysql",
"--skip-networking",
f"--socket={socket}"
])
self.connect_mysql()
print("Running mysql_upgrade...")
retries = 0
while retries < max_retries:
result = self.run_command([
"mysql_upgrade",
"-u", dbuser,
f"-p{dbpass}",
f"--socket={socket}"
], check=False)
if result.returncode == 0:
print("mysql_upgrade completed successfully.")
break
else:
print(f"mysql_upgrade failed (try {retries+1}/{max_retries})")
retries += 1
time.sleep(wait_interval)
else:
print("mysql_upgrade failed after all retries.")
temp_proc.terminate()
return False
print("Shutting down temporary mysqld...")
self.run_command([
"mariadb-admin",
"shutdown",
f"--socket={socket}",
"-u", dbuser,
f"-p{dbpass}"
])

View File

@@ -0,0 +1,28 @@
FROM mariadb:10.11
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
RUN apt-get update && \
apt-get install -y --no-install-recommends \
python3 \
python3-pip \
gosu \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN pip install \
mysql-connector-python \
jinja2 \
redis \
dnspython
COPY data/Dockerfiles/bootstrap /bootstrap
COPY data/Dockerfiles/mariadb/docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["mysqld"]

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Run hooks
for file in /hooks/*; do
if [ -x "${file}" ]; then
echo "Running hook ${file}"
"${file}"
fi
done
python3 -u /bootstrap/main.py
BOOTSTRAP_EXIT_CODE=$?
if [ $BOOTSTRAP_EXIT_CODE -ne 0 ]; then
echo "Bootstrap failed with exit code $BOOTSTRAP_EXIT_CODE. Not starting MariaDB."
exit $BOOTSTRAP_EXIT_CODE
fi
echo "Bootstrap succeeded. Starting MariaDB..."
exec gosu mysql "$@"

View File

View File

@@ -17,16 +17,18 @@ services:
- unbound - unbound
mysql-mailcow: mysql-mailcow:
image: mariadb:10.11 image: ghcr.io/mailcow/mariadb:nightly-19052025
depends_on: depends_on:
- unbound-mailcow - unbound-mailcow
- netfilter-mailcow - netfilter-mailcow
stop_grace_period: 45s stop_grace_period: 45s
volumes: volumes:
- ./data/hooks/mariadb:/hooks:z
- ./data/conf/mysql/:/etc/mysql/conf.d/:z
- mysql-vol-1:/var/lib/mysql/ - mysql-vol-1:/var/lib/mysql/
- mysql-socket-vol-1:/var/run/mysqld/ - mysql-socket-vol-1:/var/run/mysqld/
- ./data/conf/mysql/:/etc/mysql/conf.d/:ro,Z
environment: environment:
- CONTAINER_NAME=mysql-mailcow
- TZ=${TZ} - TZ=${TZ}
- MYSQL_ROOT_PASSWORD=${DBROOT} - MYSQL_ROOT_PASSWORD=${DBROOT}
- MYSQL_DATABASE=${DBNAME} - MYSQL_DATABASE=${DBNAME}