docker入门之mysql

docker火了那么久,自己在平时也常常听别人说docker怎么怎么样(假装能听懂的样子),后来还是决定自己撸起袖子就开干,因为自己平时也有练习一些小项目,断断续续的,当时解决了,后来隔断时间不用就又忘记了,俗话说好记性不如烂笔头,这次就把实践的全部记下来了,以防未来又忘记了(‍♀️)

准备步骤

安装 docker

你要用docker,那么三部曲无外乎就是安装,编码,运行,所以我们首先来安装 docker。安装 docker 有很多种方式,网上教程也是五花八门;这里就跳过,毕竟网上一大把,贴一个菜鸟的教程
docker 安装好了,就可以使用简单的命令去查看了;常用的有:

docker images  // 查看当前本地镜像
docker pull imagename  // 获取一个新镜像
docker search imagename  // 查找一个镜像
docker rmi images-id  // 删除一个镜像
docker image prune --force --all  // 删除所有不使用的镜像
docker ps -a // 查看容器
docker rm container-id // 删除容器
docker stop container-id // 停止容器

当然还有很多 docker builddocker run 等命令,可以去查阅其具体用法

拉取镜像

docker 安装好了,我们使用命令去获取一个 mysql 的镜像

docker pull mysql:5.6

note
:5.6:表示版本
这个时候我们使用查看命令就可以看到该镜像已经在本地了

docker入门之mysql_第1张图片
查看镜像.png

运行

docker 安装好了,镜像也获取了,那么现在就可以基于该镜像起一个容器了

运行容器

docker run -itd --name some-mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.6

note

  1. -itd: -i 以交互模式运行容器,通常与 -t 同时使用;-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用;-d 后台运行容器,并返回容器ID
    2.--name [name]:容器名称
    3.-p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 宿主机ip:3306 访问到 mysql 的服务。
    3.-e MYSQL_ROOT_PASSWORD=my-secret-pw:设置 mysql 服务 root 用户的密码。
    这个时候我们使用查看容器命令,就可以看见该容器已经运行起来了
    4.-d mysql:[version]:这里指基于哪个版本的镜像来生成容器
查看容器.png

进入实例

容器已经运行起来了,我们就可以使用命令进入到实例里

docker exec -it container-name bash

然后输入 mysql -uroot -p 输入我们刚刚设置的密码,就能正常操作数据库了

docker入门之mysql_第2张图片
数据库.png

这样我们就基于官方 mysql 镜像,运行起了一个数据库实例,我们也可以使用其他数据库客户端去连接该数据库,不过如果你是基于最新的数据库创建的实例,连接可能会失败,说找不到image not found,那么你可能需要进入 mysql 实例去修改下密码

ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'root';

数据初始化

虽然上面我们已经生成了数据库实例,但是在实际中,我们希望在创建实例的过程中就能初始化我们写好的 sql 脚本,刚好 mysql 的官方镜像可以支持在容器启动的时候自动执行指定的 sql 脚本或者 shell 脚本,我们能看见官方镜像中 Dockerfile 部分代码:

COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]

EXPOSE 3306
CMD ["mysqld"]

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

echo
  for f in /docker-entrypoint-initdb.d/*; do
  case "$f" in
    *.sh)     echo "$0: running $f"; . "$f" ;;
    *.sql)    echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;;
    *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;;
    *)        echo "$0: ignoring $f" ;;
  esac
  echo
done

说的是会遍历 docker-entrypoint-initdb.d 目录下所有的 .sh.sql 后缀的文件并执行。所以我们的思路是将数据库初始化脚本拷贝到 docker-entrypoint-initdb.d 目录下。那么接下来我们就编写 Dockerfile 文件

  • Dockerfile
#基础镜像使用 mysql:5.6
FROM mysql:5.6

#作者
MAINTAINER cc <[email protected]>

#定义工作目录
ENV WORK_PATH /usr/local/work

#定义会被容器自动执行的目录
ENV AUTO_RUN_DIR /docker-entrypoint-initdb.d

#定义sql文件名
ENV FILE_0 init_table.sql 
ENV FILE_1 init_data.sql

#定义shell文件名
ENV INSTALL_DB_SHELL init_db.sh

#创建文件夹
RUN mkdir -p $WORK_PATH

#把数据库初始化数据的文件复制到工作目录下
COPY ./$FILE_0 $WORK_PATH/
COPY ./$FILE_1 $WORK_PATH/

#把要执行的sql文件放到/docker-entrypoint-initdb.d/目录下,容器会自动执行这个sql
COPY ./$INSTALL_DB_SHELL $AUTO_RUN_DIR/

#给执行文件增加可执行权限
RUN chmod a+x $AUTO_RUN_DIR/$INSTALL_DB_SQL
  • init_db.sh
#!/bin/bash
mysql -uroot -p$MYSQL_ROOT_PASSWORD << EOF
source $WORK_PATH/$FILE_0;
source $WORK_PATH/$FILE_1;
  • init_table.sql
CREATE DATABASE IF NOT EXISTS test;

use test;

CREATE TABLE IF NOT EXISTS user (
  id INT NOT NULL AUTO_INCREMENT,
  account VARCHAR(32) NOT NULL,
  password VARCHAR(32) NOT NULL,
  openId VARCHAR(100) DEFAULT NULL,
  createdAt DATETIME DEFAULT CURRENT_TIMESTAMP,
  updatedAt DATETIME DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);
  • init_data.sql
INSERT INTO user (account, password) values ('admin', '123456');

生成镜像

文件编写好了,我们就能基于该 Dockerfile 构建一个镜像

docker build -t init_mysql .

note:

  1. -t:镜像名,可跟上版本,eg init_mysql:0.0.1
  2. .: 表示 Dockerfile 在当前路径下
  3. 更多命令可以使用 docker build --help 查看
    这时就能查看到我们刚刚生成了镜像了
镜像.png

运行容器

镜像生成后,我们就可以去运行一个容器了

docker run -itd --name demo-mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root -d test_mysql
容器.png

我们进入实例就可以看见刚刚初始化好的表以及数据

docker入门之mysql_第3张图片
数据库.png

当然也可以使用客户端连接,同样也能看见


docker入门之mysql_第4张图片
客户端.png

总结

好了,恭喜你到此,折腾半天后,可以在 docker 里面放肆的使用数据库。人生也不过如此,在于折腾,以及折腾后的成功,心情也会很愉快。尽管是搬砖,但也是自己实际动手操作过。我是一名搬砖工,专注搬砖,谢谢,附上源码吧,如需请自取(尽管它很简单)

你可能感兴趣的