zoukankan      html  css  js  c++  java
  • docker 生成mysql镜像启动时自动执行sql

    文章转载自:https://www.jianshu.com/p/12fc253fa37d

    在docker 创建 mysql 容器时,往往需要在创建容器的过程中创建database 实例,代码如下:

    # MYSQL_ROOT_PASSWORD=123456,指定 root 用户名密码 123456 
    # MYSQL_DATABASE=my_db 创建数据库实例 my_db
    docker run -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_DATABASE=my_db mysql:latest
    

    但有时我们还希望在创建实例的过程中初始化我们的sql脚本,mysql的官方镜像可以支持在容器启动的时候自动执行指定的sql脚本或者shell脚本,我们一起来看看mysql官方镜像的Dockerfile,如下图:

    已经设定了ENTRYPOINT,里面会调用/entrypoint.sh这个脚本,脚本其中一段内容如下图:

    遍历docker-entrypoint-initdb.d目录下所有的.sh和.sql后缀的文件并执行。

    原理清楚了,那我们就开始动手操作,思路是将数据库初始化脚本拷贝到docker-entrypoint-initdb.d 目录下,编写Dockerfile 文件,内容如下:

    fileName: Dockerfile

    #基础镜像使用 mysql:latest
    FROM mysql:latest
    
    #作者
    MAINTAINER aaa <aaaa@sohu.com>
    
    #定义会被容器自动执行的目录
    ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
    
    #定义初始化sql文件
    ENV INSTALL_DB_SQL init_database.sql
    
    #把要执行的sql文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个sql
    COPY ./$INSTALL_DB_SQL $AUTO_RUN_DIR/
    
    #给执行文件增加可执行权限
    RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DB_SQL
    

    fileName: init_database.sql

    -- 建库
    CREATE DATABASE IF NOT EXISTS my_db default charset utf8 COLLATE utf8_general_ci;
    
    -- 切换数据库
    use my_db;
    
    -- 建表
    DROP TABLE IF EXISTS `table1`;
    
    CREATE TABLE `table1` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(20) DEFAULT NULL COMMENT '姓名',
    `age` int(11) DEFAULT NULL COMMENT '年龄',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- 插入数据
    INSERT INTO `table1` (`id`, `name`, `age`)
    VALUES
    (1,'姓名1',10),
    (2,'姓名2',11);
    

    生成镜像:

    # “init_mysql:0.0.1”为镜像名称,“.” 表示Dockerfile在当前路径下,可以通过
    docker build -t init_mysql:0.0.1 .
    

    根据镜像生成容器:

    # “--name mysql” 指定容器名字,“-p 12345:3306”指定容器暴漏的端口号,“init_mysql:0.0.1” 镜像名称
    docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d init_mysql:0.0.1
    

    登陆进容器中,进入容器后登录mysql,可以看到my_db 已存在,table1已创建,表中已有初始化数据

    docker exec -it mysql bin/bash
    
    root@a55d00da8d79:/# mysql -uroot -p123456;
    mysql> show databases;
    mysql> use my_db;
    mysql> select * from table1;
    

    但以上方式有个问题,就是如果有多个sql文件,无法保证执行顺序,这就需要引入 sh 文件,思路是在docker-entrypoint-initdb.d 目录下放置 sh 文件,在 sh 文件中依次执行 sql 文件,编写Dockerfile、install_db.sh、init_database.sql、init_table.sql、init_data.sql 文件,内容如下:

    fileName: Dockerfile

    #基础镜像使用 mysql:latest
    FROM mysql:latest
    
    #作者
    MAINTAINER aaa <aaa@sohu.com>
    
    #定义工作目录
    ENV WORK_PATH /usr/local/work
    
    #定义会被容器自动执行的目录
    ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d
    
    #定义sql文件名
    ENV FILE_0 init_database.sql 
    ENV FILE_1 init_table.sql
    ENV FILE_2 init_data.sql
    
    #定义shell文件名
    ENV INSTALL_DB_SHELL install_db.sh
    
    #创建文件夹
    RUN mkdir -p $WORK_PATH
    
    #把数据库初始化数据的文件复制到工作目录下
    COPY ./$FILE_0 $WORK_PATH/
    COPY ./$FILE_1 $WORK_PATH/
    COPY ./$FILE_2 $WORK_PATH/
    
    #把要执行的shell文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个shell
    COPY ./$INSTALL_DB_SHELL $AUTO_RUN_DIR/
    
    #给执行文件增加可执行权限
    RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DB_SHELL
    

    fileName:install_db.sh

    mysql -uroot -p$MYSQL_ROOT_PASSWORD << EOF
    source $WORK_PATH/$FILE_0;
    source $WORK_PATH/$FILE_1;
    source $WORK_PATH/$FILE_2; 
    

    fileName:init_database.sql

    CREATE DATABASE IF NOT EXISTS my_db default charset utf8 COLLATE utf8_general_ci;
    

    fileName:init_table.sql

    use my_db;
    
    DROP TABLE IF EXISTS `table1`;
    
    CREATE TABLE `table1` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `name` varchar(20) DEFAULT NULL COMMENT '姓名',
      `age` int(11) DEFAULT NULL COMMENT '年龄',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    fileName:init_data.sql

    use my_db;
    
    INSERT INTO `table1` (`id`, `name`, `age`)
    VALUES
        (1,'姓名1',10),
        (2,'姓名2',11);
    

    生成镜像和容器代码如上,这里就不重复了。

  • 相关阅读:
    LG P4213【模板】杜教筛(Sum)
    JZOJ 3447.摘取作物
    JZOJ 3448.公路维护
    JZOJ 4496. 【GDSOI 2016】第一题 互补约数
    jmeter的参数化之函数助手的使用
    window10平台运行jenkins.war的插件安装失败的解决
    jmeter的断言之响应断言的使用
    在虚拟机里安装完mysql后,开启root远程登录权限
    Word Excel PPT 2016从新手到高手
    Oracle 如何停止正在后台执行的impdp/expdp 任务
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/15215434.html
Copyright © 2011-2022 走看看