ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

创建带有自定义库的Mysql镜像

2020-08-22 10:32:08  阅读:255  来源: 互联网

标签:自定义 -- Mysql mysql process entrypoint sql 镜像 docker


默认情况下,在mysql容器中创建新库时需要先运行mysql容器,把需要的sql文件通过docker cp的方式拷贝至容器内,再通过mysql的子命令将sql文件导入。过程比较繁琐,如果是公司的项目部署,可以创建带有公司的项目sql的自定义mysql镜像,避免繁琐的流程。

背景分析

首先拉取官方镜像:

docker pull mysql:5.7.30

查看镜像的构建历史

[root@bochs docker]# docker history mysql:5.7.30 
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
...               
<missing>           29 hours ago        /bin/sh -c #(nop)  ENTRYPOINT ["docker-entrypoint.sh"]   0B                              
...    

可以发现,默认的entrypoint为docker-entrypoint.sh

进入容器内,可以发现docker-entrypoint.sh其实是个软连接

lrwxrwxrwx   1 root root   34 May 15 20:11 entrypoint.sh -> usr/local/bin/docker-entrypoint.sh

查看此脚本,发现脚本中已经定义了初始化的代码:

1、docker_process_init_file()函数定义了初始文件的格式,其中调用了docker_process_sql来完成新库创建及数据导入。

初始化文件可以是.sh .sql .sql.gz .sql.xz格式中的任一种

  docker_process_init_files() {
          # mysql here for backwards compatibility "${mysql[@]}"
          mysql=( docker_process_sql )
  
          echo
          local f
          for f; do
                  case "$f" in
                          *.sh)
                                  # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936
                                  # https://github.com/docker-library/postgres/pull/452
                                  if [ -x "$f" ]; then
                                          mysql_note "$0: running $f"
                                          "$f"
                                  else
                                          mysql_note "$0: sourcing $f"
                                          . "$f"
                                  fi
                                  ;;
                          *.sql)    mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
                          *.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;;
                          *.sql.xz) mysql_note "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;;
                          *)        mysql_warn "$0: ignoring $f" ;;
                  esac
                  echo
          done
}

2、docker_process_sql使用mysql命令导入数据库文件

docker_process_sql() {
         passfileArgs=()
         if [ '--dont-use-mysql-root-password' = "$1" ]; then
                 passfileArgs+=( "$1" )
                 shift
         fi
        
         if [ -n "$MYSQL_DATABASE" ]; then
                 set -- --database="$MYSQL_DATABASE" "$@"
         fi
 
         mysql --defaults-extra-file=<( _mysql_passfile "${passfileArgs[@]}") --protocol=socket -uroot -hlocalhost --socket="${SOCKET}" "$@"
}

3、在主函数调用了docker_process_init_file()函数,初始化的文件全部位于/docker-entrypoint-initdb.d/

365         docker_process_init_files /docker-entrypoint-initdb.d/*

只要把sql文件放入该目录我们就可以通过docker build命令来创建带有自定义库的mysql镜像了。

实现过程

创建新的Dockerfile文件,将所需要的用到的sql文件拷贝到/docker-entrypoint-initdb.d/目录中

 FROM mysql:5.7.30
 COPY ./mysql/initsql/*.sql /docker-entrypoint-initdb.d/

docker-compose文件如下

version: "3.3"
   
services:
  mysql:
    build:
      context: .
      dockerfile: Dockerfile
    image: mysql_modified:v1.0
    container_name: mysql_modified
    ports:
     - target: 3306
       published: 3306
       protocol: tcp
       mode: host
    volumes:
       - /home/docker/mysql/conf/:/etc/mysql/conf.d/
       - /home/docker/mysql/data/:/var/lib/mysql/
    environment:
       - MYSQL_ROOT_PASSWORD=Zxczxc@123

新建测试用的test.sql文件

注意:如果是用mysqldump导出的sql文件,必须要加上-B参数保留创库语句。

CREATE DATABASE IF NOT EXISTS DB_TEST;

USE DB_TEST;
 
CREATE TABLE employees (
    emp_no       INT             NOT NULL COMMENT '主键',
    birth_date    DATE           NOT NULL COMMENT '生日',
    first_name   VARCHAR(14)     NOT NULL COMMENT '用户-姓',
    last_name    VARCHAR(16)     NOT NULL COMMENT '用户-名',
    gender        ENUM ('M','F') NOT NULL COMMENT '性别',
    hire_date     DATE           NOT NULL COMMENT '入职时间',
    PRIMARY KEY (emp_no)
);

INSERT INTO `employees` VALUES 
(10001,'1953-09-02','Georgi','Facello','M','1986-06-26'),
(10002,'1964-06-02','Bezalel','Simmel','F','1985-11-21'),
(10003,'1959-12-03','Parto','Bamford','M','1986-08-28'),
(10004,'1954-05-01','Chirstian','Koblick','M','1986-12-01');

整个构建目录结构如下:

[root@bochs /]# tree home
home
`-- docker
    |-- docker-compose.yml
    |-- Dockerfile
    `-- mysql
        |-- conf
        |   `-- my.cnf
        |-- data
        `-- initsql
            `-- test.sql

5 directories, 4 files

使用docker-compose build命令构建新的带有默认库mysql镜像

[root@bochs docker]# docker-compose build
Building mysql
Step 1/2 : FROM mysql:5.7.30
 ---> b84d68d0a7db
Step 2/2 : COPY ./mysql/initsql/*.sql /docker-entrypoint-initdb.d/
 ---> c64103df17a2

Successfully built c64103df17a2
Successfully tagged mysql_modified:v1.0

[root@bochs docker]# docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql_modified      v1.0                c64103df17a2        32 seconds ago      448MB
mysql               5.7.30              b84d68d0a7db        30 hours ago        448MB

完成镜像创建后使用docker-compose up -d启动该容器并查看数据,新库已成功创建,数据也正常。

[root@bochs docker]# docker-compose up -d

[root@bochs docker]# docker exec -it  mysql_modified mysql -uroot -p'Zxczxc@123' -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database           |
+--------------------+
| information_schema |
| DB_TEST            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

[root@bochs docker]# docker exec -it  mysql_modified mysql -uroot -p'Zxczxc@123' -e 'select * from DB_TEST.employees;\G'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10003 | 1959-12-03 | Parto      | Bamford   | M      | 1986-08-28 |
|  10004 | 1954-05-01 | Chirstian  | Koblick   | M      | 1986-12-01 |
+--------+------------+------------+-----------+--------+------------+

总结

放入/docker-entrypoint-initdb.d/目录中的文件只会在构建镜像时执行一次

可以将多个数据库放入/docker-entrypoint-initdb.d/中达到批量化创建的目的

标签:自定义,--,Mysql,mysql,process,entrypoint,sql,镜像,docker
来源: https://www.cnblogs.com/ltzhang/p/13544633.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有