文章转载自: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);

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

docker 生成mysql镜像启动时自动执行sql的更多相关文章

  1. 让docker中的mysql启动时自动执行sql

    在用docker创建mysql容器的时,有时候我们期望容器启动后数据库和表已经自动建好,初始化数据也已自动录入,也就是说容器启动后我们就能直接连上容器中的数据库,使用其中的数据了. 其实mysql的官 ...

  2. 让docker中的mysql启动时自动执行sql文件

    本文提要 本文目的不仅仅是创建一个MySQL的镜像,而是在其基础上再实现启动过程中自动导入数据及数据库用户的权限设置,并且在新创建出来的容器里自动启动MySQL服务接受外部连接,主要是通过Docker ...

  3. SAS启动时自动执行代码

    有时候我们希望SAS启动时自动执行已经编写好的程序,可以按照以下方法实现: 首先正常打开SAS,编写我们想要让SAS启动时自动执行的代码,例如获取桌面文件夹路径,以便在其他程序中引用这个路径. pro ...

  4. 详解如何在 Linux 启动时自动执行命令或脚本

    我一直很好奇,在启动 Linux 系统并登录的过程中到底发生了什么事情.按下开机键或启动一个虚拟机,你就启动了一系列事件,之后会进入到一个功能完备的系统中,有时,这个过程不到一分钟.当你注销或者关机时 ...

  5. java Web 启动时自动执行代码的几种方式

    Web容器启动后执行代码的几种方式,其执行顺序为:4===>5===>1===>2===>3,即指定init-method的Bean开始执行,接着实现spring的Bean后置 ...

  6. Linux(CentOS)启动时自动执行脚本(rc.local)

    一.Linux开机启动有多种方法,比如我设置mysql开机启动为:chkconfig --level 35 mysqld on 二.下面说说通过rc.local文件进行开机启动: 1.首先创建一个启动 ...

  7. Linux(CentOS)启动时自动执行脚本(rc.local)

    下面说说通过rc.local文件进行开机启动 1.首先创建一个启动脚本,这里以启动docker为例 创建 docker-startup.sh 脚本 #! /bin/bash /usr/bin/mk-d ...

  8. [转]在BBB启动时自动加载dtbo(或执行脚本、运行程序)

    启动时自动加载dtbo,实际上就是做了一个cape.官方推荐的方法是用eeprom来实现,请参考我的博文<为BBB制作专属自己的cape(一)>和<为BBB制作专属自己的cape(四 ...

  9. 查询事件状态,mysql查看事件是否开启,设置启动时自动开启方法

    1.查看事件是否开启 SHOW VARIABLES LIKE 'event_scheduler' 2.设置当前事件开启 SET GLOBAL event_scheduler = 1; 或 SET GL ...

随机推荐

  1. JavaWEB04-Maven&Mybatis

    今日内容 `Maven` Maven `Maven`概念&简介 Maven `Maven`安装配置 Maven `Maven`基本使用 Idea集成 `Idea`集成`Maven` Maven ...

  2. APISpace 号码实时查询API接口 免费好用

    最近公司项目有一个号码实时查询的小功能,想着如果用现成的API就可以大大提高开发效率,所以在网上的API商店搜索了一番,发现了 APISpace,它里面的号码实时查询API非常符合我的开发需求.   ...

  3. Spring Bean 标签解析

    上一篇文章讲到了标签在 parseDefaultElement 方法中进行解析,本篇文章将讲解这部分内容 bean 标签解析 查看 processBeanDefinition 方法,针对各个操作作具体 ...

  4. 同时安装py2和py3-安装多版本python

    遇到问题和需求 我的电脑环境:先安装py2再安装py3,平时我工作中是使用python2,如何保证两个版本共存且让代码来选择要使用的版本. 遇到问题 在cmd中输入python,进入的是py2的环境, ...

  5. 老子云携手福昕鲲鹏,首次实现3D OFD三维版式文档的重大突破

    你见过能动起来的文档吗? 这可不是动图,也不是视频,而是可以直接自由交互3D模型的3D OFD文档! OFD可能有人不熟悉,它其实是国产"PDF",3D OFD则突破了以往文字.图 ...

  6. HTTP协议-工作原理及消息结构

    HTTP协议 HTTP协议是Hyper Test Transfer Protocol(超文本传输协议)的缩写 适用于从万维网(WWW:World Wide Web)服务器传输超文本到本地浏览器的传输协 ...

  7. [eJOI2019]异或橙子 题解

    简要题面 维护一个数据结构,支持单点修改,询问区间所有子区间的异或和的异或和 . 做法 首先,题目要求所有子区间的异或和的异或和,发现每个元素异或两次就变成 \(0\),所以考虑统计每个元素出现的次数 ...

  8. C#/VB.NET 替换 PDF 文件上的现有图像

    我们都知道对PDF文件进行修改和编辑不是一件容易的事.但有时当我们想用新的图像来替换PDF文件上的现有图像时,该怎么办呢?别担心,本文将向您展示如何在 C#/VB.NET 中替换 PDF 文件中的现有 ...

  9. tqdm和zip组合使用时无法显示进度条-解决办法

    问题 单独对于可迭代对象iterator使用tqdm时,结合循环就可以在终端显示进度条, 以直观展示程序进度,如下: from tqdm import tqdm textlist = [] for i ...

  10. 记一次血淋淋的MySQL崩溃修复案例

    摘要:今天给大家带来一篇MySQL数据库崩溃的修复案例 本文分享自华为云社区<记一次MySQL崩溃修复案例,再也不用删库跑路了>,作者: 冰 河. 问题描述 研究MySQL源代码,调试并压 ...