需求

制作一个 MySQL Docker 镜像并初始化数据库信息

环境

  • win 11
  • Docker-Desktop 4.14.0 (91374)

分析

启动一个MySQL容器很容易。如何初始化数据呢?
大概我们会尝试很多操作,比如百度常见到 使用 CMD 命令调用shell脚本,通过shell脚本处理初始化数据等等,经过实践,这些都不太方便。
其实,MySQL 官方提供了很简单的方案,用户只需要准备好 初始化脚本,并把这些初始化脚本在制作镜像时拷贝到 MySQL 镜像内的 /docker-entrypoint-initdb.d 文件夹中即可。

MySQL 数据初始化机制

在 Docker hub 官网中,MySQL镜像首页提供了很多初始化数据的方式,包括数据的导入、导出等。下面是官方对使用 /docker-entrypoint-initdb.d 初始化数据的描述:

原文

When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.

译文

首次启动容器时,将创建具有指定名称的新数据库,并使用提供的配置变量进行初始化。此外,它将执行扩展名为 /docker-entrypoint-initdb.d 中的扩展名 .sh、.sql 和 .sql.gz 的文件。文件将按字母顺序执行。您可以通过将 SQL 转储挂载到该目录中来轻松填充 mysql 服务,并为包含贡献数据的自定义映像提供。默认情况下,SQL 文件将导入到 MYSQL_DATABASE 变量指定的数据库中。

实例

本例将通过 Dockerfile 构建一个docker 镜像,并在该容器中初始化数据。

1、编写 Dockerfile

创建Dockerfile文件,并输入如下内容

FROM mysql:5.7

# 将 xzbd.sql 放到 docker 初始化文件家中
COPY xzbd.sql /docker-entrypoint-initdb.d/xzbd.sql

该镜像基于 MySQL 5.7 制作,命名 COPY xzbd.sql /docker-entrypoint-initdb.d/xzbd.sql 是把初始化 SQL 添加到 MySQL 镜像的 /docker-entrypoint-initdb.d 目录中

2、xzbd.sql 文件

该文件为自定义的数据库文件,内容如下:

create database if not exists xzbd;
use xzbd;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for x_item
-- ----------------------------
DROP TABLE IF EXISTS `x_item`;
CREATE TABLE `x_item`
(
    `id`     INT AUTO_INCREMENT PRIMARY KEY,
    `name`   VARCHAR(10) NOT NULL COMMENT '元素名称',
    `status` VARCHAR(10) NOT NULL COMMENT '元素状态',
    `icon`   VARCHAR(50) NOT NULL COMMENT 'ICON',
    `type`   VARCHAR(50) NOT NULL COMMENT '类型',
    CONSTRAINT x_item_name_uindex UNIQUE (name)
) ENGINE = InnoDB
  CHARACTER SET = utf8mb4 COMMENT 'X子项'
  ROW_FORMAT = Dynamic;

-- 初始化 X子项
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (27, 'XItem02', 'ENABLE', 'ITEM_9', 'ITEM_9');
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (28, 'XItem03', 'ENABLE', 'ITEM_10', 'ITEM_10');
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (29, 'XItem04', 'ENABLE', 'ITEM_11', 'ITEM_11');
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (30, 'XItem05', 'ENABLE', 'ITEM_12', 'ITEM_12');
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (31, 'XItem06', 'ENABLE', 'ITEM_13', 'ITEM_13');
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (32, 'XItem07', 'ENABLE', 'ITEM_14', 'ITEM_14');
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (33, 'XItem08', 'ENABLE', 'ITEM_15', 'ITEM_15');
INSERT INTO `x_item`(`id`, `name`, `status`, `icon`, `type`) VALUES (34, 'XItem08', 'ENABLE', 'ITEM_16', 'ITEM_16');

该脚本中主要做了如下内容

  • 创建了一个数据库 xzbd
  • 创建表 x_item
  • 给表 x_item 中插入8 条数据

文件准备及目录结构如下图所示:
在这里插入图片描述

3、构建镜像

构建镜像 mysql-xzbd:0.1.0 , 命令如下:


docker build -t mysql-xzbd:0.1.0 .

注意命令最后的那个 .

构建过程如下:

在这里插入图片描述

构建成功后,使用 docker images 查看是否有 mysql-xzbd 镜像,且版本为 0.1.0

结果如下:

在这里插入图片描述

上图中使用了 findstr 过滤,在 linux 操作系统应将其换为 grep

4、运行

使用刚刚构建的 mysql-xzbd:0.1.0 镜像运行一个容器。

# 运行容器
docker run --name mysql-xzbd-servevr -it -d -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 mysql-xzbd:0.1.0

# 查看是否启动成功
docker ps

在这里插入图片描述

5、验证

验证容器 mysql-xzbd-servevr 中是否创建了数据库 xzbd,并查看其内部是否有 x_item 表,且内部是否拥有初始化数据。

  • 进入容器

docker exec -it mysql-xzbd-servevr sh

  • 登录 MySQL

mysql -uroot -p

输入密码 123456 。登录成功后效果如下:

在这里插入图片描述

  • 查看数据库
show databases;

  • 查看数据表

use xzbd;

show tables;

  • 查看表 x_item 中的数据

select * from x_item;

在这里插入图片描述

总结

本文介绍了使用Dockerfile构建有初始化数据MySQL镜像包的详细过程。通过验证,使用 /docker-entrypoint-initdb.d 初始化数据是可行的。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐