Docker中MariaDB用托管卷正常,绑定映射卷启动异常求助
自定义MariaDB镜像绑定本地目录启动失败排查
我基于Debian构建了自定义MariaDB镜像(练习要求不能用Dockerhub官方镜像),使用Docker托管卷或单独运行时都正常,但切换到本地绑定卷后服务启动失败,service mysql start执行报错,日志提示无法连接socket。
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;
docker-compose.yml配置
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"
启动错误日志
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!
排查与解决方法
1. 修复本地目录权限(核心问题)
Docker绑定本地目录时,宿主机目录的权限会直接映射到容器内。MariaDB运行用户为mysql(默认UID/GID为106/106),如果宿主机目录的所有者不是该UID/GID,容器内的mysql用户无法读写目录,导致服务启动失败。
解决操作:
- 宿主机端修改目录权限:
sudo chown -R 106:106 /Users/myusername/Documents/some/path/not/important/data/mariadb - 或者在
launch.sh启动服务前添加权限修复:chown -R mysql:mysql /var/lib/mysql chmod -R 700 /var/lib/mysql
2. 替换service mysql start为原生mysqld初始化
Debian的service命令依赖systemd环境,但Docker容器通常没有完整的systemd,这会导致服务启动异常。建议改用原生mysqld命令初始化:
修改launch.sh中的初始化逻辑:
if [ ! -d "/var/lib/mysql/$MYSQL_DATABASE" ]; then echo "/var/lib/mysql/$MYSQL_DATABASE directory doesnt exist"; # 初始化数据库目录 mysqld --initialize-insecure --user=mysql # 启动临时mysqld进程 mysqld --user=mysql & # 等待进程完全启动(比sleep更可靠) until mysqladmin ping -h localhost --silent; do sleep 1 done # 执行数据库配置SQL 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
3. 检查50-server.cnf配置有效性
确保配置文件中的socket路径和数据目录正确,同时允许本地连接:
[mysqld] socket = /var/run/mysqld/mysqld.sock datadir = /var/lib/mysql bind-address = 0.0.0.0
4. 清理本地目录残留文件
如果之前启动失败,本地目录可能残留无效的socket或pid文件,清理后重试:
rm -rf /Users/myusername/Documents/some/path/not/important/data/mariadb/*
内容的提问来源于stack exchange,提问作者Foxan
相关产品推荐
相关产品推荐

