Compose启动mysql:8.0如何配置支持新增用户及执行init.sql

在 Docker Compose 中启动 mysql:8.0 并自动执行初始化的 init.sql 脚本以及创建新用户,主要利用 MySQL 官方镜像的特性:.sql 脚本挂载到容器内的 /docker-entrypoint-initdb.d/ 目录


1. 项目结构

创建如下目录结构:

1
2
3
mysql-project/
├── docker-compose.yml
└── init.sql

2. 编写 init.sql

MySQL 8.0 默认使用 caching_sha2_password 身份验证插件。在 init.sql 中,你可以编写建表语句以及额外的账户创建和权限分配命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- 创建新数据库(如果环境变量里没指定)
CREATE DATABASE IF NOT EXISTS `app_db` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 创建新用户并设置密码
CREATE USER IF NOT EXISTS 'dev_user'@'%' IDENTIFIED BY 'DevUserPassword123!';

-- 授予该用户对 app_db 的全部权限
GRANT ALL PRIVILEGES ON `app_db`.* TO 'dev_user'@'%';

-- 刷新权限使其生效
FLUSH PRIVILEGES;

-- 初始化表数据
USE `app_db`;

CREATE TABLE IF NOT EXISTS `users` (
`id` INT AUTO_INCREMENT PRIMARY KEY,
`username` VARCHAR(50) NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `users` (`username`) VALUES ('Alice'), ('Bob');

3.docker-compose.yml

通过环境变量设置 Root 密码,并将本地的 init.sql 挂载至容器内的 /docker-entrypoint-initdb.d/ 目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
services:
mysql:
image: mysql:8.0
container_name: mysql_server
restart: always
ports:
- "3306:3306"
environment:
# 设置 root 密码
MYSQL_ROOT_PASSWORD: RootPassword123!
# (可选)也可以通过环境变量直接创建一个默认数据库和普通用户:
# MYSQL_DATABASE: app_db
# MYSQL_USER: dev_user
# MYSQL_PASSWORD: DevUserPassword123!
volumes:
# 挂载数据持久化目录
- mysql_data:/var/lib/mysql
# 将初始化脚本挂载到官方指定的执行目录
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro

volumes:
mysql_data:

4. 启动与验证

启动服务

在包含 docker-compose.yml 的目录下执行:

1
docker compose up -d

验证脚本是否执行

你可以进入容器查看日志或连接数据库验证:

  1. 查看日志确认初始化成功:
1
docker compose logs mysql

日志中会出现 /docker-entrypoint-initdb.d/init.sql: running 相关的提示。

  1. 使用新建的用户登录测试:
1
docker exec -it mysql_server mysql -udev_user -pDevUserPassword123! app_db

注意事项

  • init.sql只会在数据库第一次创建时自动执行!MySQL 镜像会检查挂载的 mysql_data 卷中是否已有数据。如果卷中已经包含数据文件,/docker-entrypoint-initdb.d/ 下的任何脚本都不会被再次触发。