这段时间,一直用docker部署内网,踩了很多坑,尤其是数据库,有时候感觉很棘手,有时候问题解决了,却还是很疑惑。先来总结一下如何用docker启动mysql。
step1 制作mysql镜像
一般我们都需要数据库里面的数据支持中文,但是mysql默认字符集是latain,而它是不支持中文的,mysql在 5.5.3 之后增加了 utf8mb4 字符编码,mb4即 most bytes 4。简单来说,utf8mb4 是 utf8 的超集并完全兼容utf8,能够用四个字节存储更多的字符。我们可以用官方的docker mysql image制作一个支持utf8mb4的mysql镜像。
首先,创建mysql的配置文件utf8mb4.cnf,如下:
|
|
然后,创建Dockerfile文件,基于mysql官方的docker镜像,将utf8mb4.cnf 复制到容器的/etc/mysql/conf.d/目录下,构建新镜像:
|
|
在当前文件夹构建镜像,添加标签:
|
|
最后启动一个容器:
|
|
docker run 会启动一个mysql容器在后台运行,并设置其名字,把相应的参数设为mypassword,这个参数用于登录这个mysql容器,mysql容器默认开放3306端口,3306时容器对主机的端口,6603是主机对外界的端口,设置这个参数可以直接通过外界访问到mysql容器的内部。
step2 在mysql容器中创建数据库
|
|
获取主机中mysql容器的地址
|
|
进入容器,这时可以查看mysql容器的字符集情况
|
|
可以看到:
它们的含义如下
|
|
说明容器支持utf8mb4 。
创建数据库:
|
|
step3 配置docker-compose.yml 和 .env 文件
在docker-compose.yml文件中加入
|
|
意为外连一个名为
在.env 文件中设置数据库的URL,使用刚才在mysql容器中创建的数据库 ,形如:
|
|
注意这里要使用IPAddress,IPAddress是mysql容器的IP地址,否则它会提示找不到localhost,之后会出现无法迁移数据库的情况。
step4 初始化数据库
使用
|
|
能操作容器。
所以,可以对运行在容器的内的服务进行如下操作:
|
|
在这个过程中,我碰到了一些问题,关于migrations文件。运行docker exec
比如这样: 和
按理来说migrations不应该在本机生成。虽然生不生成migrations不影响数据库迁移,但是这很奇怪。
后续如果数据库中的模型有所变更,应使用如下命令迁移数据库:
|
|
step5 解决中文字符
如果直接使用官方的mysql docker image,则无法支持中文字符,要修改mysql容器的字符设置,利用以下命令进入mysql容器:
|
|
进入mysql容器之后,登录mysql:
|
|
查看当前mysql字符集情况 可以看到:
database和service的字符集设定是Latin1,不支持中文,如果要支持中文,就要把要数据库编码修改为utf8mb4,但是我把这个mysql的配置和数据库的配置称utf8mb4,依旧不支持中文(这就很气
所以这是一个未解之谜,以后再解决吧。
step6 数据库迁移
之前我迁移数据库,由于各种原因不成功的时候,总是非常粗暴地直接进到服务的容器里面,直接把migrations删了重新,重新建一个。然而,运行到
|
|
的时候,总是有一个报错:
这是因为Alembic在数据库里保存了版本记录,虽然migrations已经删掉了,但是alembic_version还保留着它的版本,所以要把它删掉。
进入mysql容器,登录mysql,查找创建的数据库,果然发现里面有一个alembic_version:
查看alembic_version:
把alembic_version删除 :
|
|
这样就不会报错了。
最后
还是有很多很奇怪的地方,但好在问题都有了解决办法,,所以先不管它。