最小可行配置只需指定mysql_root_password环境变量和正确挂载/var/lib/mysql路径,缺一即导致容器秒退;其他如端口映射、配置文件、初始化数据库等均为可选优化项。

直接能跑起来的最小可行配置,只需要 MYSQL_ROOT_PASSWORD 和挂载 /var/lib/mysql,其他全是可选优化项。漏掉密码或挂错路径,容器会秒退,别在日志里反复猜原因。
容器启动就退出?先盯住 MYSQL_ROOT_PASSWORD
MySQL 8.0+ 官方镜像强制校验该环境变量,空值、未定义、或者只写在 .env 里但没被 docker-compose.yml 显式引用,都会导致容器启动失败并立刻退出。
- 必须在
environment块里明写,例如:MYSQL_ROOT_PASSWORD: my-secret-pw - 避免纯数字或常见弱密码,否则会被 MySQL 密码策略拒绝(报错类似
ERROR 1819 (HY000)) - 如果用
.env文件注入,确保docker-compose.yml中写的是MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD},且.env文件存在且可读
volumes 挂载错位置,数据就丢了
MySQL 容器默认把数据存在 /var/lib/mysql,挂载点写成 /data 或 /db 是常见错误——容器会用临时文件系统存数据,一重启全清空。
- 宿主机路径必须是**绝对路径**或以
./开头的相对路径,例如:./mysql-data:/var/lib/mysql:rw - 不要写成
mysql-data:/var/lib/mysql,这会被 Docker 当作命名卷,你无法直接查看或备份宿主机上的文件 - 首次运行前,建议手动创建目录并赋权:
mkdir -p ./mysql-data && chown -R 999:999 ./mysql-data(MySQL 容器内 UID 默认为 999)
想连上数据库?别只靠服务名
在 Compose 网络里,服务之间用服务名(如 mysql)通信没问题;但如果你从宿主机用 mysql -h 127.0.0.1 -P 3306 连,实际走的是端口映射,得确认 ports 是否正确暴露,且 MySQL 没绑定 127.0.0.1 本地回环。
- 加
command: --bind-address=0.0.0.0确保监听所有接口(MySQL 8.0 默认是127.0.0.1) -
ports写法要带冒号,例如:- "3306:3306",不是- 3306 - 如果应用容器要连 MySQL,host 直接写服务名(
mysql),不用加端口(默认 3306),除非你改了ports映射
时区和初始化 SQL 怎么加?
时区不一致会导致 NOW()、慢查询日志时间戳等出问题;初始化 SQL 则用于自动建库建表,避免每次手动执行。
- 时区:加
TZ: Asia/Shanghai环境变量,并在command里补--default-time-zone='+08:00',两者都设才稳 - 初始化 SQL:把
.sql文件放宿主机某目录(如./initdb/),然后挂载到容器内/docker-entrypoint-initdb.d/,MySQL 启动时会自动执行(仅首次初始化有效) - 注意:
/docker-entrypoint-initdb.d/下的脚本只在/var/lib/mysql为空时运行,已有数据不会重复执行
真正容易被忽略的是权限和首次初始化逻辑:挂载目录宿主机 UID 不匹配,或 initdb 脚本放在了错误路径,都会让容器看似正常运行,实则没生效。动手前先 ls -l 看一眼目录属主,比查半天日志快得多。











