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:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -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/*
|
||||||
|
|||||||
@@ -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
|
||||||
},
|
},
|
||||||
|
|||||||
80
data/Dockerfiles/bootstrap/modules/BootstrapMysql.py
Normal file
80
data/Dockerfiles/bootstrap/modules/BootstrapMysql.py
Normal 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}"
|
||||||
|
])
|
||||||
28
data/Dockerfiles/mariadb/Dockerfile
Normal file
28
data/Dockerfiles/mariadb/Dockerfile
Normal 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"]
|
||||||
20
data/Dockerfiles/mariadb/docker-entrypoint.sh
Normal file
20
data/Dockerfiles/mariadb/docker-entrypoint.sh
Normal 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 "$@"
|
||||||
0
data/hooks/mariadb/.gitkeep
Normal file
0
data/hooks/mariadb/.gitkeep
Normal 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}
|
||||||
|
|||||||
Reference in New Issue
Block a user