🎉 前言
事情是这样的,我最近不是在学docker吗,在网上找了一堆教程,有一个视频里讲了如何部署后端和数据库,然后跟着视频一步一步来,结果发现踩了不少坑,花了将近5个小时,终于解决了,因此在这里记录一下,以作为前车之鉴。
🎉 准备工作
后端项目工程结构
创建后端镜像的命令:(Server文件夹中执行)
docker build -t my-node-app:v1 .
创建后端容器:(Server文件夹中执行)
docker run -p 9421:80 --name testProject my-node-app:v1
创建mysql容器的命令:
docker run -d --name mysql -p 3333:3306 -e TZ=Asia/Shanghai -e MYSQL_ROOT_PASSWORD=123 mysql:8.0
这里是因为本地已经有mysql8.0版本了,所以直接执行docker run了,如果本地没有,会从docker hub中pull一个镜像并创建容器。
🎉 问题描述
问题主要落实在了三个地方:
- 是否将后端容器和mysql容器放在了同一个网络空间下
- mysql容器的数据库中是否有数据
- 后端中连接数据库的代码是否有问题
问题1
先来说第一个问题,这个到好办,只要执行一下命令就可以让两个容器处于一个网络之下:
docker network create qiuchuang
先建立一个名叫qiuchuang
的网络,然后让两个容器分别连接这个网络
docker network connect qiuchuang testProject
docker network connect qiuchuang mysql
至此,第一个问题解决。
问题2
这个问题我是这么解决的:
- 使用宿主机的navicat去连接容器里的数据库,注意端口号在之前创建mysql容器时映射的是宿主机的
3333
端口,密码设置的是123
,用户名是root
- 将新建连接命名为docker,然后再新建数据库
demo
- 将自己原先的项目中创建的表“导出向导”,然后在新建数据库中“导入向导”,这样就在新建的数据库中导入了数据
- 打开docker-desktop,使用mysql客户端执行相关指令检查是否已有数据,如图显示说明有数据:
总结一下,我实际上干了这么两件事,第一,使用宿主机的navicat连接容器中的数据库,然后向其导入数据,这样操作比较方便。第二,使用docker-desktop进入容器中的数据库中查看是否导入数据成功。
至此,第二个问题也解决了。
问题3
这个问题说实话我一开始还真没发现哪里错了,可能是掌握的知识太少了,导致没有发现,不过结果还是好的。
一开始的后端连接数据库的文件中的host是127.0.0.1,后来chat了一下,说这里的127.0.0.1指的是后端容器,我一想也有道理,后来得知在同一个网络下只要将其指定为容器名称即可,也就是这里的mysql:
改完之后,还是失败,我在想,难道还要指定端口号为3333吗,后来想了一下,心里骂了自己一句:“脑子瓦特啦,这个3333是映射的宿主机的端口,容器里的mysql还是3306,这个是默认端口,无需额外指定”,我一想,也对。于是到这里我又卡住了。
后来我又使用postman去访问后端的各种路由,我突然惊奇地发现在访问comment路由时返回了一个报错(可能因为这是唯一一个get请求的原因):
Client does not support authentication protocol requested by server; consider upgrading MySQL client
, 错误码是1251
事实上,前几天我在帮同学解决bug的时候遇到过这个问题,当时也解决了,于是我打算采用一下当时解决这个问题的方法。博客链接:MySql错误 1251 - Client does not support authentication protocol requested by server 解决方案.
这里提到这样两行指令:
alter user 'root'@'localhost' identified with mysql_native_password by '123';
flush privileges;
尝试了一下,哈哈,还是没用,此时此刻,我的内心不能说是心如死灰吧,至少也算是万念俱灰了。
最后,凭着最后一丝残存的意志,我又开始检查前面提到的那三个问题,发现怎么改都没有用,最后兜兜转转又回到了那个1251
的问题上,这次我几乎是怀着死马当活马医的心态,又看了一篇博客,这篇博客可以说是对之前的那篇起到了一个补充作用,经过这次补充,总算解决了这个”顽疾“。
🎉 最后的挣扎
现在让我们来看一下这篇博客,到底在哪里对之前那篇博客进行了补充。博客地址:Mysql 解决1251- Client does not support authentication protocol requested by server…的问题,两个相同用户名密码不一致导致
文章里提到使用这条命令来查看信息:
select host,user,plugin,authentication_string from mysql.user;
首先,打开mysql容器命令行,进入mysql控制台,输入上面这条指令,出现以下内容
这里需要说明一下,这是更改以后的图,在执行了之前那篇博客里面的命令后,只有最后一行的plugin项发生了变化,第一行并没有。
后来这篇博客里提到的解决方法中包含对第一行host为“%
”修改的方法,指令如下:(注意密码不一定是“123”哦)
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123';
其实这篇文章还提到了对host为localhost
的修改方法,指令如下:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123';
实际上这条指令就是之前我看的那篇文章里面提到的指令,但是那篇文章没有提到修改host为“%
”的方法,而这正是整个问题的关键之所在!谢天谢地,这篇文章让我得到了“救赎”。
🎉 尾声
其实除了之前遇到的这几个问题,我还遇到过使用别人的命令将mysql密码给改了,然后又要删除镜像,修改文件内容等一系列操作,这样下来,整个人都快疯了。因此,可以想象,在经历了这么多挫折之后,最终问题得以解决,内心的喜悦简直难以言表,于是写下这篇带有日志感觉的博客,记录下我现在的心情,也让自己有个前车之鉴,日后再遇到这种问题可以有迹可循。OK,我是秋窗,又是踩坑的一天,今天已经够累了,我们下期再见👋。