解决群晖Docker安装MySQL时区问题
前段时间在群晖NAS的Docker里安装了MySQL,方便自己折腾result API开发,最近在开发时遇到了一个问题,就是数据库的时间跟北京时间相差8小时,会导致时间判断出错,这里记录一下解决办法,供遇到同样问题的同学参考。
问题描述
在做邮箱+验证码登录的功能时,我们将javascript
生成的验证码和过期时间存到了数据库的表中。然而在利用过期时间做查询校验时,却发现不管验证码过没过期,都查不到任何数据。
1 |
|
排查过程
一开始以为是生成验证码和过期时间的函数有问题,但是不管是console.log()
,还是查看数据库表的存储,过期时间确实没啥问题。
1 |
|
于是我将怀疑对象转向了MySQL的NOW()
方法,果断进入Docker容器,输入命令来验证我的猜想。
进入容器的方法:打开群晖Docker,点击容器——MySQL——详情——终端机,进入容器内部,输入用户名和密码,登录MySQL数据。
进入容器登录以后,输入select now();
,查看打印的时间,通过打印结果观察,果然是数据库的时间不对。
1 |
|
继续输入show variables like '%time_zone%';
来查看MySQL的时区。
1 |
|
观察可知,time_zone
的值是SYSTEM
,也就是取了群晖Docker的时区,我们继续查看Docker容器所属的时区。
1 |
|
至此,真相大白了。
我们通过上面的排查,可以确定,问题出在了安装MySQL时未指定时区,而MySQL会默认取Docker容器所属的时区,而Docker容器默认的时区又是+0000,所以数据库的时间与中国时间相差了8个小时。
解决方案
既然知道了问题原因,自然而然的就可以列出解决方向:
- 修改Docker系统所属的时区。
- 修改MySQL所属的时区。
修改Docker容器(未验证成功)
网上很多文章都写了这个方案,然后我尝试了,很遗憾失败了。可能是因为我的Docker安装位置是群晖的NAS系统。不管是从上面的终端机还是使用putty连接NAS,输入该命令只会得到docker: command not found
。
1 |
|
对Docker比较熟悉的小伙伴遇到这个问题可以尝试一下这个方案是否可行。
修改MySQL所属的时区(验证成功)
还是通过终端机登录MySQL,可以用以下命令来临时修改MySQL所属的时区。
1 |
|
但因为我们的MySQL安装在了Docker里,一旦Docker遇到意外发生故障或者重启,该配置就会失效,所以我们要想办法将它永久化。
在另一篇笔记《群晖NAS使用指北-Docker安装MySQL》中,为了使数据库的数据永久化,我们在宿主机创建了三个文件夹logs、conf、data
来进行映射。
在电脑中新建一个mycustom.txt
文件,写入以下配置:
1 |
|
上面的配置会指定MySQL的时区,另存为改文件或者直接重命名改后缀为mycustom.cnf
,将该文件放入NAS中我们先前创建的conf文件夹中。
重新启动MySQL容器,进入终端机,登录数据库,会发现提示一个报错。
1 |
|
这个报错的意思是:mycustom.cnf
这个文件的权限太大了,任何人都可以修改,不太安全,MySQL会忽略其中的配置。导致这个问题的原因是因为conf
文件夹的权限我们设置为了任何人都可以读取/写入。
右键该文件夹,点击属性——权限,编辑Everyone的权限设置为读取,把写入都给勾掉。
如果权限列表都是灰色的,就点高级选项——使继承权限显示化,再继续上述步骤即可。
修改完后重启MySQL,登录终端机,查看修改效果,发现已经OK了。
1 |
|
小结
这篇笔记主要是对Docker中MySQL时区不正确的问题做一个复盘和记录。问题本身并不复杂,但是对于像我这种纯前端同学,初玩后端还不太熟练的话,解决起来也确实需要费一番功能。就像让纯后端同学去调试css样式一样难受,哈哈!