# Docker MySQL
MySQL 的 Docker 镜像在 dockerhub 上的地址:https://hub.docker.com/_/mysql (opens new window)
当前(2021-04-02)的 latest 和 8.0.23 是同一个镜像 。另外,5.7 版本和 5.7.33 是同一个镜像。
# 1. 安装及测试
# 查询中央仓库
docker search -f is-official=true mysql
# 从中央仓库下载
docker pull mysql:8.0.16
# 或,直接导入已有的镜像文件
# docker load -i mysql-8.0.16.tar
# 查看本地镜像
docker images
# 会出现类似如下内容:
# REPOSITORY TAG IMAGE ID CREATED SIZE
# mysql 8.0.16 de764ad211de 2 years ago 443MB
运行容器:
# 删除曾经已有的同名容器
docker rm -f mysql-test
# 创建并运行 mysql 容器的语法
docker run \
-d \
--name <指定容器名> \
-p <指定宿主机端口>:3306 \
-e MYSQL_ROOT_PASSWORD=<指定root登录密码> \
mysql:8.0.16
例如:
docker run \
-d \
--name mysql-3306 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0.16
# docker run -d --name mysql-3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.16
验证安装成功
# 查看容器的运行信息
docker ps
# 进入 mysql-test 容器
docker exec -it mysql-test /bin/bash
# 执行 mysql-cli 的连接命令
mysql -uroot -p123456
后续可选操作:
对 root 的远程连接授权
容器逻辑上等价于另一台电脑。而在 mysql 中,root 用户默认只能从 MySQL Server 所在的电脑上登陆,无法从『另一台』电脑通过远程连接的方式登陆。
当然,这种『默认』行为是可以配置的。
按上述命令,从容器内部连接到 MySQL Server,执行如下 SQL 语句:
> use mysql; > select user, host from user; > GRANT ALL ON *.* TO 'root'@'%'; > flush privileges;
从容器外部连接
> mysql -h <宿主机IP> -P <宿主机端口号> -u root -p <root登陆密码>
# 2. 配置与挂载
MySQL Server 的数据的存储目录容器中的 /var/lib/mysql/ ,你在 MySQL 中存储的数据,就被 MySQL 放在了这个目录下。
MySQL Server 的配置文件是容器中的 /etc/mysql/my.cnf + /etc/mysql/conf.d/mysql.cnf 。
关于 MySQL 的配置文件和配置项:
MySQL Server 启动时会去加载 /etc/mysql/my.cnf
配置文件,这个配置文件中有一部分配置。一般情况下我们不会去动这部分内容,也不会在这个配置文件中追加内容。
在 my.cnf
配置文件的最后,它又引入了另一个目录 /etc/mysql/conf.d/
,MySQL 会加载这个目录下的所有的 .cnf 配置文件的配置信息。虽然可以在这个下面新建配置文件,不过 MySQL 已经提前帮我们建立好了一个名为 mysql.cnf
配置文件(默认情况下,它里面除了注释啥都没有,是个空文件)。对于我们自己想要设置的配置项,我们将它们写在这里面。
配置文件中常见的 [mysqld]、[client] 和 [mysql]
[mysqld]
代表数据库自身的默认设置
[client]
代表客户端默认设置内容
[mysql]
代表我们使用 mysql 命令连接、登录 MySQL Server 时的默认设置
由于 mysql 命令本身也是 mysql server 的客户端之一,因此,当你使用 mysql 命令连接 mysql server 时,[client]
和 [mysql]
配置都会起作用。
示例
# 删除已存在的同名容器 docker rm -f mysql-3306 # 创建宿主机挂载目录 mkdir -p ~/docker/3306/{config,data} # 创建 mysql.cnf 配置文件 touch ~/docker/3306/config/mysql.cnf # 在宿主机的 **conf** 目录下新建任意命名的 `.cnf` 文件,其中内容见最后。 # 创建并运行容器 docker run \ -d \ --name mysql-3306 \ -v ~/docker/3306/data:/var/lib/mysql \ -v ~/docker/3306/config/mysql.cnf:/etc/mysql/conf.d/mysql.cnf \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql:8.0.16
# 3. docker-compse 方式启动
version: '3'
services:
mysql-3306:
image: mysql:8.0.16
network_mode: "bridge" # 默认值
container_name: mysql-3306
mem_limit: 512m # 限定 docker 容器内存大小
environment:
- MYSQL_ROOT_PASSWORD=123456
volumes:
- /etc/localtime:/etc/localtime:ro # 时区
- ~/docker/3306/data:/var/lib/mysql # 数据
- ~/docker/3306/config/mysql.cnf:/etc/mysql/conf.d/mysql.cnf # 配置
ports: # network_mode: "host" 无需端口映射
- "3306:3306"
启动命令:docker-compose up -d mysql-3306
# 4. 初始化数据库
mysql 的 docker 镜像有一个功能:它在第一次创建容器(重启不算)时,会到容器内的 /docker-entrypoint-initdb.d
目录下查看有没有 sql 脚本,如果有,就执行 sql 脚本。因此,你可以通过这个功能来完成数据库的创建等初始化工作。
你可以在某个目录下创建 .sql 脚本(例如 init.sql),并在其中写上建库、建表等 SQL 语句,然后将这个目录映射成 /docker-entrypoint-initdb.d
。
# 5. mysql.cnf
默认是空的。我们加点东西:指定字符集。
[mysqld]
character_set_server=utf8
[mysql]
default-character-set=utf8