本文最后更新于:2024年11月7日 上午

之前记录过 MySQL 的基础知识,本文记录使用 Docker 自动部署、初始化表结构的操作流程 。

背景

在测试机器上配置好了一组 MySQL 环境,手工一条一条设计、配置、调整得到了几个数据表,希望可以将这些表结构、mysql 数据库很方便地移植到任意服务器上,于是有了本文记录的流程。

准备工作

环境配置

  • 操作系统:Ubuntu 22.04
  • 安装好 docker
  • 配置好 docker compose
  • 使用 MySQL docker 镜像 mysql 8.0.38

实现思路

  1. 将数据表导入 init.sql 文件
  2. 在构建 mysql 镜像时将 sql 文件塞入 /docker-entrypoint-initdb.d/ 目录下,mysql 会自动调用其中的 sql 文件完成初始化
  3. 将流程 2 用 dockerfile 的方式实现
  4. 将流程 3 与配置磁盘映射、端口映射、用户密码、时区统一等信息用docker compose 的方式实现
  5. 为了配合流程 4 的时区、磁盘映射等功能,将辅助工作与流程 4 用 shell 脚本的方式实现
graph LR
subgraph shell
    subgraph docker-compose

        subgraph Dockerfile
        A(数据表信息)
        B(init.sql)
        A--导出-->B
        end
        I(构建镜像)
        C(配置数据库密码)
        D(配置数据库端口)
        E(配置磁盘映射)
        F(配置时区)
    end
    G(时区文件配置)
    H(创建数据库映射文件夹)
    J(创建容器)
end

最终达到运行一个shell 脚本万事大吉的效果

init.sql 文件生成

执行命令:

  • 单个数据库:
1
mysqldump -h [hostname] -u [username] -p --port=[port] [databasename] --no-data > init.sql
  • 所有数据库:
1
mysqldump -h [hostname] -u [username] -p --port=[port] --no-data --all-databases > init.sql

形如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-- MySQL dump 10.13  Distrib 5.7.24, for Linux (x86_64)
--
-- Host: 192.168.10.116 Database: test
-- ------------------------------------------------------
-- Server version 8.0.38

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `foobar_info`
--

CREATE DATABASE IF NOT EXISTS test;
USE test;


DROP TABLE IF EXISTS `foobar_info`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `foobar_info` (
`id` char(32) NOT NULL,
`model` varchar(128) NOT NULL,
`desc` varchar(256) DEFAULT NULL,
`lat` decimal(16,12) NOT NULL,
`lon` decimal(16,12) NOT NULL,
`alt` decimal(16,12) NOT NULL,
`project_id` int NOT NULL,
`time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT 'VARCHAR(256)',
PRIMARY KEY (`id`),
UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

过程中可以添加用户信息:

1
2
CREATE USER 'username'@'%' IDENTIFIED BY 'passwd';
GRANT ALL PRIVILEGES ON test.* TO 'username'@'%';

注意:

在用 dockerfile 构建镜像时会将临时结果保存在 docker images 里,如果更新了 init.sql 需要删除对应的 docker 镜像,不然默认还是会用之前镜像中的内容。

Dockerfile

1
2
3
4
5
6
7
8
# 使用官方 MySQL 8.0.38 版本作为基础镜像
FROM mysql:8.0.38

# 设置时区
ENV TZ=Asia/Shanghai

# 将初始化脚本复制到容器中
COPY init.sql /docker-entrypoint-initdb.d/

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
services:
mongodb:
build:
dockerfile: Dockerfile
container_name: mysql8
ports:
- "33306:3306"
restart: always
environment:
- TZ=Asia/Shanghai
- SET_CONTAINER_TIMEZONE=true
- CONTAINER_TIMEZONE=Asia/Shanghai
- MYSQL_ROOT_PASSWORD=123456
volumes:
- /etc/localtime:/etc/localtime:ro
- /data/mysql/data:/var/lib/mysql
- /data/mysql/conf:/etc/mysql/conf.d
- /data/mysql/log:/var/log
- /data/mysql/share:/share

shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/bin/bash

# 检查当前用户是否是root
if [ "$(id -u)" -ne 0 ]; then
echo "此脚本需要以root用户运行,请使用sudo运行此脚本。"
exit 1
fi

# 定义一个函数 create_dir_if_not_exists
create_dir_if_not_exists() {
local dir_path="$1"
# 检查目录是否存在
if [ ! -d "$dir_path" ]; then
# 如果不存在,则创建目录
mkdir -p "$dir_path"
echo "目录 '$dir_path' 已创建。"
else
# 如果存在,则打印消息并跳过创建
echo "目录 '$dir_path' 已存在,无需创建。"
fi
}

make_mysql_dirs(){
local root_dir="$1"
local data_dir=$root_dir"/data"
create_dir_if_not_exists $data_dir
local conf_dir=$root_dir"/conf"
create_dir_if_not_exists $conf_dir
local share_dir=$root_dir"/share"
create_dir_if_not_exists $share_dir
local log_dir=$root_dir"/log"
create_dir_if_not_exists $log_dir
}

# 使用函数创建目录
make_mysql_dirs /data/mysql

echo "Shanghai 时区同步"
sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

echo "同步时钟"
sudo hwclock --systohc

# 启动容器
docker-compose -f docker-compose.yml up -d

使用方法

docker-compose.ymlDockerfileinit.sqlmysql_deploy.sh 放到一个文件夹,执行:

1
sudo ./mysql_deploy.sh


文章链接:
https://www.zywvvd.com/notes/coding/dataset/mysql/mysql-deploy/mysql-deploy/


“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信二维码

微信支付

支付宝二维码

支付宝支付

MySQL Docker 自动部署实战
https://www.zywvvd.com/notes/coding/dataset/mysql/mysql-deploy/mysql-deploy/
作者
Yiwei Zhang
发布于
2024年10月23日
许可协议