mysql Docker容器如何运行_mysql镜像部署与数据持久化

6次阅读

必须挂载 /var/lib/mysql 目录,否则容器重启后数据丢失;root 密码需通过 -e mysql_root_password 设置;端口映射用 -p 3306:3306;初始化脚本挂载到 /docker-entrypoint-initdb.d/ 且仅首次执行。

mysql Docker容器如何运行_mysql镜像部署与数据持久化

docker run 启动 mysql 容器时必须挂载 /var/lib/mysql

不挂载数据目录,容器重启后所有数据库、表、用户都会消失——这是最常踩的坑。MySQL 镜像默认把数据写在容器内部的 /var/lib/mysql,而容器删除即销毁该路径。

实操建议:

  • -v /host/path:/var/lib/mysql 显式绑定宿主机目录,例如 -v ./mysql-data:/var/lib/mysql
  • 首次运行前确保宿主机目录为空(或由 MySQL 初始化过),否则启动失败并报错 mysqld: Can't read dir of '/etc/mysql/conf.d/' 或权限拒绝
  • linux 下宿主机目录需给 chown -R 999:999 ./mysql-data(MySQL 官方镜像以 UID 999 运行 mysqld)

root 密码必须通过 MYSQ_ROOT_PASSWORD 环境变量传入

官方 mysql 镜像不接受命令行参数设密码,也不读取配置文件里的 password 字段。漏设该变量会导致容器卡在初始化阶段,日志反复输出 Waiting for MySQL to start...

实操建议:

  • 必须加 -e MYSQ_ROOT_PASSWORD=your_secure_password,不能写成 MYSQL_ROOT_PASSWORD(少个 S 就无效)
  • 密码含特殊字符(如 @$)要对 shell 做转义,或改用 --env-file 文件方式传入
  • 如果后续想换密码,不要删容器重跑,应进容器执行 ALTER USER 'root'@'%' IDENTIFIED BY 'newpass';

端口映射和远程访问需要额外开 MYSQL_ROOT_HOST

默认只允许 root@localhost 登录,宿主机用 mysql -h 127.0.0.1 -P 3306 -u root -p 会连不上,报错 access denied for user 'root'@'172.17.0.1'(Docker 网络分配的 IP)。

实操建议:

  • -e MYSQL_ROOT_HOST=% 允许任意 host 连接 root(仅开发环境用;生产请建专用用户)
  • 务必配 -p 3306:3306,注意左边是宿主机端口,右边是容器内端口,顺序反了没报错但连不通
  • 若宿主机 3306 已被占用,可映射为 -p 3307:3306,但客户端连接时必须指定 -P 3307

初始化 SQL 脚本得放对位置:容器启动时自动执行 /docker-entrypoint-initdb.d/

init.sql 直接丢进挂载的数据目录不会生效——MySQL 启动时只扫描 /docker-entrypoint-initdb.d/ 下的 .sql.sh.sql.gz 文件,且**仅当数据目录为空时执行一次**。

实操建议:

  • -v ./init.sql:/docker-entrypoint-initdb.d/init.sql 挂载脚本(注意路径拼写,少一个 / 就变成创建同名文件而非挂载)
  • 脚本里别写 CREATE database —— 官方镜像已根据 MYSQL_DATABASE 环境变量建库;重复建库会中断初始化
  • 如果容器已运行过,再挂脚本也不会执行;删容器 + 清空数据目录 + 重跑才是唯一触发方式

真正麻烦的不是命令写不对,而是数据目录权限、初始化时机、网络访问策略这三者交织在一起——调通一次之后,下次换机器或升级镜像版本,很可能因为 UID 变了或 MySQL 版本行为微调,又卡在同一个地方。

text=ZqhQzanResources