windows环境下搭建mysql数据库docker容器

windows环境下搭建mysql数据库docker容器
最近因项目需要,要在windows环境下搭建一个以容器镜像运行的mysql数据库,本以为是件简单的事情,结果遇到不少坑,所以在这里记录下来以和大家共享。

运行环境

操作系统:Windows 10家庭中文版
Windows Docker安装包:Docker Toolbox version 19.03.1
Docker compose文件:

version: "3"
services:
  mysql:
    container_name: mysql
    hostname: mysql
    image: mysql
    ports:
    - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - ./mysql_data:/var/lib/mysql
      - ./my.cnf:/etc/my.cnf
    expose:
    - "3306"
    networks:
    - "c7nNetwork"
networks:
  c7nNetwork:
    driver: bridge

因为需要对mysql运行镜像容器做数据持久化处理并进行运行参数配置,所以在docker-compose.yaml文件中分别挂载了mysql_data目录和my.cnf配置文件。
my.cnf配置文件内容:

[mysqld]
lower_case_table_names=1
character_set_server=utf8
max_connections=500

我的文件目录位置及结构:
在这里插入图片描述

操作步骤

  1. 打开“Docker Quickstart Terminal”,如下图:
    在这里插入图片描述
  2. 将运行目录切换到docker-compose.yaml文件所在目录下,如下图:
    在这里插入图片描述
  3. 输入命令"docker-compose.exe up -d"启动容器,然后输入“docker-compose.exe ps”命令查看容器运行状态,如下图所示:
    在这里插入图片描述

问题一

经过执行以上部署步骤后,mysql容器镜像运行状态貌似没有什么问题,可是仔细查看后发现了两个问题:
1.挂载的mysql_data目录下没有产生任何文件,但是容器内/var/lib/mysql目录下数据库相关文件成功生成了;
2.容器内etc目录下的my.cnf竟然不是一个文件,而是一个目录,如下图所示:
在这里插入图片描述

原因分析

从现象看,所有问题都出在存储volume的挂载处理上,根本没有达到预期挂载效果。docker-compose在挂载错误的情况下没有给出明显的提示而做了默认处理,甚至把本来要挂载的文件在错误的情况下当做目录进行了处理。
问题原因分析思路:
1.首先可以排除文件夹和文件不存在的原因,docker-compose.yaml文件的同级目录下肯定存在对应的文件夹和文件;
2.如果排除了文件夹和文件不存在的原因,那只有一种可能,就是docker-compose程序在执行挂载命令时无法找到这两个对象,那为什么会找不到呢?经过深入分析,觉得还是docker-compose程序运行环境导致,我们执行docker-compose程序时是在一个Windows的终端上,所以给了我们一个错觉,以为是在Windows本地运行,但其实不是,docker-compose程序真正执行环境是在一个VirtualBox的虚拟机里,双击“Oracle VM VirtualBox”图标,如下图所示:
在这里插入图片描述在这个虚拟机里肯定没有这两个文件夹和文件对象,这就可以解释为什么docker-compose程序没有找到对应的文件夹和文件。

解决办法

找到问题原因后解决就简单了,只要想办法将对应的文件夹和文件先共享进入虚拟机,然后再执行docker-compose命令进行挂载应该就可以了。经过调查,发现虚拟机存在一个默认的共享文件夹路径,位置在本地的C:\Users,如下图所示:

在这里插入图片描述考虑到C:\Users目录在Windows 10环境下权限控制较为严格,不太适合进行工程开发,所以决定再增加一个挂载目录用于项目开发,本人在D盘根目录下创建了一个share文件夹,然后共享到虚拟机,如下图所示:
在这里插入图片描述注意:增加新的共享目录需要先将虚拟机关闭。
将D:\WinDocker目录下的mysql文件夹整体移动D:\share文件夹下,然后重新执行docker-compose程序。在执行过后发现问题依旧,进入虚拟机查看,能够看到对应的文件夹和文件对象信息,如下图所示:
在这里插入图片描述
莫非是docker-compose程序无法解析./这种写法,尝试修改试试看,如下图所示:

version: "3"
services:
  mysql:
    container_name: mysql
    hostname: mysql
    image: mysql
    ports:
    - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - /share/mysql/mysql_data:/var/lib/mysql
      - /share/mysql/my.cnf:/etc/my.cnf
    expose:
    - "3306"
    networks:
    - "c7nNetwork"
networks:
  c7nNetwork:
    driver: bridge

然后重新执行“docker-compose.exe up -d”命令。

问题二

新的问题出现了,查看mysql运行状态,发现容器状态竟然是退出,如下图所示:
在这里插入图片描述
容器运行日志如下图所示:
在这里插入图片描述## 原因分析
通过查看mysql_data文件夹的内容,可以证明问题一的文件夹和文件挂载问题已经解决了,通过分析日志文件,可以看到两个问题:
1.容器内/etc/my.cnf文件由于权限过大而被mysqld进程因World-Writable(全局可写)的安全因素而被放弃加载;
2.出现了aio write文件写入错误,说明虚拟机不支持这种文件读写模式。

解决办法

1.修改/etc/my.cnf文件权限为644,经过测试,如果直接在容器里修改此文件权限不起作用,原因大概可能和Windows挂载有关,所以解决思路是首先完成挂载,然后在启动脚本里拷贝出一份再修改权限,因为mysql镜像启动默认会执行docker-entrypoint.sh脚本,所以首先需要将这个脚本从一个正常镜像中拷贝出来,修改后再挂载回去,具体如下:

version: "3"
services:
  mysql:
    container_name: mysql
    hostname: mysql
    image: mysql
    ports:
    - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - /share/mysql/mysql_data:/var/lib/mysql
      - /share/mysql/my.cnf:/etc/my.cnf
      - /share/mysql/docker-entrypoint.sh:/usr/local/bin/docker-entrypoint.sh
    expose:
    - "3306"
    networks:
    - "c7nNetwork"
networks:
  c7nNetwork:
    driver: bridge

修改docker-entrypoint.sh文件,在文件开头增加内容,具体如下所示:

#!/bin/bash
cp /etc/my.cnf /etc/mysql/conf.d/mysql_db.cnf
chmod 644 /etc/mysql/conf.d/mysql_db.cnf

2.在my.cnf配置文件中增加一行参数:innodb_use_native_aio=0,具体如下所示:

[mysqld]
lower_case_table_names=1
character_set_server=utf8
max_connections=500
innodb_use_native_aio=0

修改完成后将前次执行时mysql_data目录下已经生成的文件全部删除,然后再次执行"docker-compose.exe up -d"命令,这次mysql数据库终于可以正常启动了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值