前段时间建了个misskey实例,其实我当时就在考虑要不要过段时间等作者的13版本发布了再建,因为当时看到作者的帖子说13已经快发布了,最后犹豫了一下还是决定就先装12.119.2算了。
当时看了下官方docker-compose里面的配置,就觉得postgresql和redis的版本都好旧了,又在考虑要不要自己改下版本tag,最后还是怕出现不兼容的问题也没有改就直接跑起来了,下面这是我当时正在用的配置:
version: '3.5' services: web: image: misskey/misskey:latest restart: unless-stopped links: - db - redis networks: - internal_network - external_network ports: - "127.0.0.1:3000:3000" volumes: - ./files:/misskey/files - ./config:/misskey/.config:ro redis: image: redis:4.0-alpine restart: unless-stopped networks: - internal_network volumes: - ./redis:/data db: image: postgres:12.2-alpine restart: unless-stopped networks: - internal_network env_file: - ./config/docker.env volumes: - ./db:/var/lib/postgresql/data networks: internal_network: internal: true external_network:
postgresql容器用到的docker.env,里面的配置:
POSTGRES_PASSWORD=passwd POSTGRES_USER=misskey POSTGRES_DB=misskey
也就过了半个月左右,现在13发布了,看到新增加的一些功能和界面的改动心里痒痒,想着升级下。。没想到整个升级过程不是很顺利,走了很多弯路。。
misskey13需要postgresql15,这东西跨版本升级不能直接改tag,因为数据结构不同,直接改tag拉新的image是跑不起来的。。
google搜了下,普遍的解决办法是先备份旧数据,然后再恢复。问题就出在这里,给我整的头皮发麻,把官方的文档看了个遍,最后算是整明白了。。
这里我记录下2种可行的备份、恢复方法,先说第一种。
我个人也推荐第一种:使用pg_dump备份数据库,使用pg_restore恢复数据库。
进入到misskey的项目目录:
cd /opt/misskey
先停掉web容器,防止有新的数据写到数据库:
docker compose stop web
备份数据库,完成之后在当前目录会有db.dump文件,这个就是备份出来的二进制数据:
docker compose exec db pg_dump -Fc misskey -U misskey > db.dump
数据备份完成后停止并删除所有容器:
docker compose down
在之前的docker-compose中可以看到这个postgresql数据库没有用到命名卷,仅仅是将主机的目录挂载到了容器内,所以保险起见,我们可以先把这个目录重命名一下:
mv db db.bak
这也可以说算是一种备份,如果你有足够的信心直接删掉这个目录也行。
接下来编辑docker-compose.yml文件:
nano docker-compose.yml
修改image的tag:
image: postgres:12.2-alpine
将12.2改为15:
image: postgres:15-alpine
(可选)redis的tag也可以改一下:
image: redis:4.0-alpine
目前官方的docker-compose.yml文件里面已经是7了:
image: redis:7-alpine
拉新的image下来:
docker compose pull
先启动db容器:
docker compose up -d db
恢复数据:
docker compose exec -T db pg_restore -U misskey -d misskey < db.dump
等待恢复完成,查看db容器的日志:
docker compose logs db
确保里面没有报错信息,之后将全部容器都up起来:
docker compose up -d
下面来说第二种方法,使用pg_dumpall备份数据,使用psql恢复数据。(不推荐这种方法)
这种方法和上面的区别在于pg_dumpall备份出来的数据是纯文本的,pg_dumpall也只支持这一种格式。
纯文本格式的数据不能使用pg_restore恢复,只能使用psql恢复。并且pg_dumpall会导出Roles,这里就是大坑所在。
还是先停止web容器:
docker compose stop web
使用pg_dumpall备份数据:
docker compose exec db pg_dumpall -U misskey > db.sql
停止并删除其他所有容器:
docker compose down
重命名挂载目录:
mv db/ db.backup
由于postgresql15将默认的host验证方式从md5改成了scram-sha-256(在postgresql14之前都是md5,14之后就是scram-sha-256)
又因为pg_dumpall备份出来的数据是包含roles的,所以这里需要把postgresql15容器的host验证方式改回和之前一样的都使用md5,否则会导致misskey程序无法连接数据库。
编辑docker-compose.yml文件里面指定的envfile:
nano ./config/docker.env
加入如下配置:
POSTGRES_HOST_AUTH_METHOD=md5
修改image的tag:
image: postgres:12.2-alpine
将12.2改为15:
image: postgres:15-alpine
(可选)redis的tag也可以改一下:
image: redis:4.0-alpine
目前官方的docker-compose.yml文件里面已经是7了:
image: redis:7-alpine
拉新的image:
docker compose pull
启动db容器:
docker compose up -d db
导入数据:
docker compose exec -T db psql -U misskey < db.sql
导入完成后查看日志,看看有没有报错:
docker compose logs db
如果遇到下面的这些错误可以忽略,这是因为容器在启动的时候已经创建了同名的role和数据库:
ERROR: role "misskey" already exists ERROR: database "misskey" already exists
最后将全部容器都启动:
docker compose up -d
小记:
使用这种方法需要注意的是POSTGRES_HOST_AUTH_METHOD变量仅在容器初始化的时候生效,也就是说如果容器已经启动过一次了,再设置这个变量是不起作用的:
https://github.com/docker-library/postgres/issues/981
如果要修改已经启动过的容器,可以编辑pg_hba.conf:
nano db/pg_hba.conf
文件的末尾有一行这样的配置:
host all all all scram-sha-256
修改为:
host all all all md5
重启容器使其生效:
docker compose restart db
至此两种postgresql数据库备份、恢复方法都介绍完了。剩下的是与misskey相关的操作。
根据这个新的更改:
https://github.com/misskey-dev/misskey/pull/9560
以及如果你遇到了这些问题:
https://github.com/misskey-dev/misskey/issues/9564
https://github.com/misskey-dev/misskey/issues/9608
那么你还需要修改misskey文件目录所有者,然后重启:
cd /opt/misskey chown -hR 991.991 files docker compose restart
最后清理下无用的docker image:
docker images // 找到镜像的id,然后用rmi命令删除 docker rmi 755f15b2f8cd docker rmi ae192c4d3ada
总结遇到的问题,一开始我是使用的pg_dumpall备份的数据库,这个工具备份出来的数据包含了数据库共有的全局对象,即数据库角色、表空间、配置参数等数据。这就是pg_dumpall和pg_dump最大的区别所在,pg_dump备份出来的数据是不含这些内容的。这是我后来仔细看了官方文档才发现的:
https://www.postgresql.org/docs/current/app-pg-dumpall.html#Description
又由于postgresql14之后的版本将默认的host验证方式从md5改为了scram-sha-256,这是我翻了半天在官方docker镜像页面发现的:
https://hub.docker.com/_/postgres
里面有这样一段话:
This optional variable can be used to control the auth-method for host connections for all databases, all users, and all addresses. If unspecified then scram-sha-256 password authentication is used (in 14+; md5 in older releases).
这样就导致恢复后的数据库还用的是旧的md5验证方式,与现有postgresql15默认的配置不兼容。最后就导致程序连接不上数据库。
最后我看了下通过pg_dumpall备份出来的纯文本数据,里面确实有这样的内容:
CREATE ROLE misskey; ALTER ROLE misskey WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS PASSWORD 'md5xxxxx';
所以,以后备份数据最好用pg_dump。。。
感谢!
长毛象哪个不用了嘛
老大,请问怎么全面的备份misskey呢?