docker部署Mysql并实现持久化存储

目标

  1. 使用docker部署Mysql
    1. 重置密码
    2. 导入表结构
  2. 持久化存储(即使删除容器的情况下)

目录结构

服务器上我的目录结构如下

root/docker/项目名称
├── mysql
│   ├── Dockerfile
│   ├── present.sql
│   ├── privileges.sql
│	└── setup.sh
└── docker-compose.yml

docker-compose.yml

version字段要根据自己使用的docker版本来决定。docker版本与此version的对应关系详见。
restart:always表示容器退出之后自动重启。

version: "3"
services: 
    mysql:
        build: ./mysql
        restart: always
        volumes:
            - "present-data-mysql:/var/lib/mysql:rw"
        ports: 
            - "3306:3306"
volumes:
    present-data-mysql: {}

ps:如果先创建卷然后使用它的话,会遇到Named volume "xxxx" is used in service "mysql" but no declaration was found in the volumes section.的错误。
为此我参考了这篇问答中toussa的写法,使用docker-compose的volumes字段,如果有present-data-mysql这个卷就会直接使用它,否则会创建一个新的卷并使用。

present.sql

此文件的作用是:初始化数据库、表结构以及导入初始数据。
大家根据实际情况来编写即可,但是这里有几点要注意:

  1. 因为我们是将数据持久化存储在卷中了,每次即使重新启动容器甚至重新构建镜像都任然使用原来的卷,所以数据不会被删除。
  2. 要注意创建表的sql文件要写成CREATE TABLE IF NOT EXISTS `表名` ()。慎用DROP TABLE IF EXISTS `表名`; CREATE TABLE `表名`()否则每次重新创建镜像的时候,表会被删除重建,表中数据随之数据也会被删除的。

下面贴出我自己的文件内容:

create database If Not Exists `present` default character set utf8 collate utf8_general_ci;
use present;

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for t_present
-- ----------------------------
CREATE TABLE IF NOT EXISTS `t_present` (
  `id` varchar(1024) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `audio_src` varchar(3000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `qrcode_src` varchar(3000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `student_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `student_class` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `student_graduation_year` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `duration_mils` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `size` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `create_time` bigint(0) NULL DEFAULT NULL,
  `file_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `token` varchar(3000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `created_at` datetime(0) NOT NULL,
  `updated_at` datetime(0) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for t_token
-- ----------------------------
CREATE TABLE IF NOT EXISTS `t_token` (
  `token` varchar(1024) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `openid` varchar(3000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `session_key` varchar(3000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `created_at` datetime(0) NOT NULL,
  `updated_at` datetime(0) NOT NULL,
  PRIMARY KEY (`token`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_token
-- ---------------------------
SET FOREIGN_KEY_CHECKS = 1;

privileges.sql

此文件的作用是:创建一个新用户,给新用户全部权限。
同样注意,由于数据是持久存储的,所以多次构建镜像的话,这一步会提示创建用户失败,因为上一次构建镜像的时候已经把创建好的用户数据写到卷中了。

use mysql;
select host, user from user;
-- 因为mysql版本是5.7,因此新建用户为如下命令:
create user docker identified by '你的密码';
-- 将docker_mysql数据库的权限授权给创建的docker用户
grant all on *.* to docker@'%' identified by '你的密码' with grant option;
-- 这一条命令一定要有:
flush privileges;

setup.sh

整个流程依赖于此shell脚本。

#!/bin/bash
set -e

#查看mysql服务的状态,方便调试,这条语句可以删除
echo `service mysql status`

echo '1.启动mysql....'
#启动mysql
service mysql start
sleep 3
echo `service mysql status`

echo '2.开始导入数据....'
#导入数据
mysql < /mysql/schema.sql
echo '3.导入数据完毕....'

sleep 3
echo `service mysql status`

#重新设置mysql密码
echo '4.开始修改密码....'
mysql < /mysql/privileges.sql
echo '5.修改密码完毕....'

#sleep 3
echo `service mysql status`
echo `mysql容器启动完毕,且数据导入成功`

tail -f /dev/null

Dockerfile

# docker image of facelog mysql
# version 1.0.0
# author guyadong
FROM mysql:5.7

#设置免密登录
ENV MYSQL_ALLOW_EMPTY_PASSWORD yes

#将所需文件放到容器中
COPY setup.sh /mysql/setup.sh
COPY present.sql /mysql/schema.sql
COPY privileges.sql /mysql/privileges.sql

#设置容器启动时执行的命令
#此时执行setup这个脚本文件,开启整个流程
CMD ["sh", "/mysql/setup.sh"]

启动

如果上面的文件都准备好了,那么直接在docker-compose.yml所在目录执行下面这条命令即可。
docker-compose up -d --force-recreate --build

参考

https://stackoverflow.com/questions/38793821/docker-compose-how-to-store-database-data
Docker最全教程——数据库容器化之持久保存数据(十一)
使用Docker部署MySQL(数据持久化)

你可能感兴趣的:(经验总结与分享)