dockerdocker-composedockerfilemariadbdocker-volume

MariaDB in Docker works with managed volume but not with mapped


I have a mariadb container running a custom image from a Dockerfile (I can't use Dockerhub images in my exercise). Everything works well alone, and with managed volume alone or in a docker-compose.

my mariadb Dockerfile :

FROM debian:buster
RUN apt-get update -y
RUN apt-get upgrade -y
RUN apt-get install mariadb-server mariadb-client -y

COPY conf/50-server.cnf /etc/mysql/mariadb.conf.d/50-server.cnf
COPY tools/launch.sh /launch.sh
RUN chmod 777 launch.sh

ENTRYPOINT ["bash",  "/launch.sh"]

launch.sh :

#!/bin/sh

if [ -d "/var/lib/mysql/$MYSQL_DATABASE" ]; then
  echo "/var/lib/mysql/$MYSQL_DATABASE directory exists";
else
  echo "/var/lib/mysql/$MYSQL_DATABASE directory doesnt exist";
  service mysql start;
  sleep 5;

  mysql -uroot -e "\
    USE mysql; \
    FLUSH PRIVILEGES; \
    DELETE FROM mysql.user WHERE User=''; \
    DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); \
    ALTER USER 'root'@'localhost' IDENTIFIED BY '${MYSQL_ROOT_PASSWORD}'; \
    CREATE DATABASE IF NOT EXISTS ${MYSQL_DATABASE}; \
    CREATE USER IF NOT EXISTS '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}'; \
    GRANT ALL PRIVILEGES ON ${MYSQL_DATABASE}.* TO '${MYSQL_USER}'@'%'; \
    FLUSH PRIVILEGES;";
  mysqladmin -uroot -p"${MYSQL_ROOT_PASSWORD}" shutdown;
fi

echo "running mysqld_safe";
mysqld_safe --user=mysql;

the docker-compose :

version: '3'

services:
  mariadb:
    container_name: mariadb
    build:
      context: requirements/mariadb
      dockerfile: Dockerfile
    env_file: .env
    volumes:
      - mariadb:/var/lib/mysql
    networks:
      - inception
    restart: always
    expose:
      - "3306"

....

volumes:
  mariadb:
#    driver_opts:
#      type: none
#      o: bind
#      device:
#"/Users/myusername/Documents/some/path/not/important/data/mariadb"

With everything like that it works well, but if I uncomment the commented volume thing to make it a mapped volume as I need to, it doesnt work anymore :

2024-01-23 17:11:06 /var/lib/mysql/inception_db directory doesnt exist
2024-01-23 17:11:37 Starting MariaDB database server: mysqld . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . failed!
2024-01-23 17:11:42 running mysqld_safe
2024-01-23 17:11:42 240123 16:11:42 mysqld_safe Logging to syslog.
2024-01-23 17:11:42 240123 16:11:42 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
2024-01-23 17:11:42 ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
2024-01-23 17:11:42 mysqladmin: connect to server at 'localhost' failed
2024-01-23 17:11:42 error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'
2024-01-23 17:11:42 Check that mysqld is running and that the socket: '/var/run/mysqld/mysqld.sock' exists!

service mysql start won't start the service correctly

I tried messing around with perms, but nothing changes, but I'm not very good at admin sys.


Solution

  • I assume by "in my exercise" you have some sadistic academic type enjoying your suffering. Please only consider this answer in this case.

    First, does it have to be buster as its really old 10.3 version, now out of support.

    The apt-get install mariadb-server will populated the /var/lib/mysql in the container. If you mount this as a volume, you'll need to use mariadb-install-db (or mysql_install_db in 10.3) to create the database when no /var/lib/mysql/mysql exists like the official image.

    service mysql start; crude, but sure.

    DELETE FROM mysql.user - not recommended, won't work with MariaDB-10.4. You'll notice the official entry point uses DROP USER IF EXISTS.

    FLUSH PRIVILEGES isn't required after creating users. Could just SHUTDOWN as a SQL command.

    You need a mechanism to ensure the shutdown is finished before the final start otherwise you'll have two MariaDB instances running on the same data, can cause corruption (and there are bug reports to prove it).

    On the final start, mysql_safe/mariadb-safe does a background process of MariaDB. Containers cannot use them as a the entrypoint must be the process (numbered on in the processes namespace). exec mysqld / exec mariadbd is one way. As the mysql user? Not strictly required, but --user=root might be needed as a mysqld argument to avoid an error. Otherwise, gosu, like the official image and exec gosu mysql /usr/sbin/mariadbd.

    From your Docker Official Images MariaDB maintainer.