将运行于Docker的Mastodon迁移到无需使用Docker的环境的方法
首先
最近,我将我管理的Mastodon实例(mastodon.noraworld.jp)从Docker环境迁移到非Docker环境。
那时候的工作对我来说相当困难,特别是数据库迁移方面让我苦恼不已。在网上搜索时,有很多关于如何用Docker构建Mastodon实例或者非Docker方式构建实例的信息,但是关于将正在运行的Docker实例迁移到非Docker的文章并不多。
我希望这篇文章能对那些正在考虑进行环境迁移的人提供参考,特别是那些缺乏网络信息而感到困惑的人。我将在这里总结我所做的工作,希望能对大家有所帮助。如果能对你有帮助,我会非常高兴。
我停止使用 Docker 的原因
我在使用Docker运行Mastodon大约四个半月的时间里发现,虽然构建环境很容易,但在性能和资源方面会成为瓶颈。
Docker 的特点是在多个环境中几乎可以构建相同的环境,而且性能下降很少。然而,经过数个月的运营,我发现使用 Docker 时响应速度稍慢,逐渐变得沉重。尽管 mastodon.noraworld.jp 自4月下旬开始运营,但到了8月下旬左右,令人担忧的延迟问题引发了我考虑迁移到非 Docker 环境。
此外,Docker的占用空间相当大。因为需要在容器中安装所有必要的二进制文件和库,即使已经在服务器根目录下安装了这些文件,也需要额外在容器内安装。显然,与在服务器根目录下安装相比,容器的效率在容量方面较低。即使容器内部设置得再整洁,Mastodon也会占用约2GB的空间。
在使用中唯一好的一点是,Mastodon本身的更新以及各个库的更新(包括安全更新)都可以通过docker-compose pull和docker-compose build来完成,但是如果只是更新Mastodon而不使用Docker,工作量是不会有任何变化的。
在我運營Mastodon的過程中,我得出的結論是,Docker主要用於快速構建開發環境和輕鬆進行重新構建等操作,但在生產環境中,除了初始環境構建外,幾乎沒有太多優點。
在阅读这篇文章之前
在这篇文章中,假设了以下几点。
-
- 作業はすべてマストドンのディレクトリ以下で行っていること
-
- バックアップを取る際のバックアップ先は ~/backup としていること
- マストドン以外のアプリケーションで Redis を使用していないこと
这些事项在没有特别注明的情况下进行了说明。备份目录应根据情况进行更改。
如果遇到错误,请求助。
如果你不知道出现错误该如何解决的话,请尝试查看下面的故障排除选项。
如果出现了在故障排除指南中未提及的错误,请首先仔细检查守护进程(服务)是否已启动或停止。
比如,在登录PostgreSQL或在Rails上迁移时,如果没有启动PostgreSQL服务器,就会出错。相反,如果尝试在启动Mastodon的Docker容器时启动PostgreSQL服务器,也会出错。有时可能会出现在PostgreSQL服务器已经启动的情况下,却尝试启动PostgreSQL 9.6服务器的错误。
意外的是,启动/停止守护进程常常是错误的根源。
确认守护进程或容器的启动状态。
要确认守护程序是否已启动,请执行以下命令。
$ systemctl status [サービス名]
例如,如果您想要确认 Redis 服务器是否已启动,请将 [服务名] 替换为 redis。
要确认Mastodon的Docker容器是否已启动,请运行以下命令。
$ docker-compose ps
如果查看故障排除指南、确认守护程序或容器的状态后仍无法解决问题,请尝试通过错误消息进行搜索。
环境
-
- CentOS 7
-
- Ruby 2.4.1
-
- Node.js 6.7.0
-
- PostgreSQL 9.6.5
-
- Redis 4.0.1
- Mastodon v1.6.0rc1
安装Ruby和Bundler。
如果服务器上还没有安装Ruby,或者已经安装的Ruby的版本与Docker内部安装的版本不同,则进行安装。尽管使用不同版本的Ruby可能不会产生大问题,但如果版本太旧可能会导致错误,因此建议安装相同版本的Ruby。
检查Docker中的Ruby版本。
$ cat .ruby-version
2.4.1
在上述的例子中,我们使用2.4.1版本所以要安装Ruby 2.4.1。
安装Ruby需要使用rbenv。关于rbenv的安装以及所需的库等,请参考”【CentOS7(+Ubuntu16)】Ruby / Rails 的安装到启动Rails服务器的(几乎)完整指南”。
$ rbenv install 2.4.1
$ rbenv rehash
如果已经安装了Ruby,那就安装Bundler。
$ gem install bundler
安装Yarn
如果尚未安装Yarn,则会安装它。要安装Yarn,首先需要安装Node.js。
个人推荐使用ndenv来安装Node.js。虽然也可以使用其他安装方法,但后续的说明将假设使用ndenv进行安装。请根据实际情况进行相应的调整。关于ndenv的安装和Node.js安装的具体步骤,请参考“使用ndenv管理多个版本的Node.js的方法和基本使用”。
顺便说一下,关于 Node.js 的版本我们没有特别的要求,但是我使用了 v6.7.0,它完美地运行了。
一旦安装了Node.js,同时也会安装npm。利用npm来安装Yarn。
$ npm install -g yarn
安装捆绑包
使用 Bundler 安装所需的 Gem。在此之前,需要安装所需的本机库。
$ sudo yum -y install libidn-devel protobuf-lite-devel postgresql-contrib
我这次安装的只有上面这些,但很可能还有其他需要安装的库。当bundle install 失败时,会显示要安装失败的Gem,然后请搜索该Gem的安装方法,并安装各自需要的本地库。由于我在其他机会已经安装了一些,所以无法完全了解现在需要什么,对此我感到有些随意,非常抱歉。
运行 bundle install。
$ bundle install --deployment --without development test
由于处于生产环境,所以会跳过只在开发和测试中需要的 Gem。
运行yarn安装
执行yarn install。
$ yarn install --pure-lockfile
安装Redis
可以按照以下步骤安装Redis。
# 個人的に非推奨
$ sudo yum -y install epel-release
$ sudo yum -y install redis
然而,使用此方法安装后,无法通过应用Redis的转储文件来启动守护进程。从错误消息来看,可能是因为Redis与Docker中使用的版本不兼容而导致无法启动守护进程。此外,在上述命令中,根据CentOS的版本,可能会提示找不到软件包而无法安装。
因此,我们将使用REMI存储库进行安装。
$ sudo yum -y install epel-release
$ wget http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
$ sudo rpm -Uvh remi-release-7*.rpm
$ sudo yum -y --enablerepo=remi,remi-test,epel install redis
可以参考以下方式来在CentOS 7.x上安装最新版本的Redis:
一旦完成 Redis 的安装后,可以删除 remi-release-7.rpm 文件,没有问题。
安装PostgreSQL
强烈建议在Docker容器中使用与PostgreSQL相同的版本。
因为这是非常重要的事情,请谨慎判断。如果 PostgreSQL 版本与 Docker 容器内的版本不一致,则在恢复备份时可能会由于兼容性原因发生错误。即使忽略错误,最重要的数据仍然可以恢复,但部分数据可能会丢失。在我的尝试中,所有用户的收藏列表、已认证应用列表和图片链接的引用数据等都消失了。
当然,如果你对数据库很了解,应该知道如何修复由于PostgreSQL升级或降级而导致的兼容性问题。但对于不熟悉的人来说,这是相当冒险的方式。顺便说一句,我自己无法解决上述问题。
因此,强烈建议安装与Docker内部版本相同的PostgreSQL。本文将介绍如何确认Docker内部的PostgreSQL版本并安装相同版本的方法。
确认版本
要确认在Docker内使用的PostgreSQL版本,请查看以下文件。
$ sudo cat postgres/PG_VERSION
9.6
在上述的例子中,我们可以看到正在使用PostgreSQL 9.6。
请假设以下说明是基于使用PostgreSQL 9.6。如果显示的版本不是9.6,则请根据需要将9.6或96的部分相应地更改。
如果找不到postgres/PG_VERSION
如果在Mastodon的目录中没有名为postgres的目录,则可以认为Docker容器内的数据没有持久化。在这种情况下,可以按以下方式进入Docker容器并检查文件。
# PG_VERSION が見つからない場合のみ
$ docker-compose up -d
$ docker exec -it mastodon_db_1 /bin/bash
$ su - postgres
$ cat data/PG_VERSION
9.6
$ exit
$ exit
请安装适用版本的PostgreSQL。
因为上述例子是9.6版本,所以我们要安装PostgreSQL 9.6。我们要添加所需的存储库并安装9.6版本。
$ sudo rpm -Uvh https://yum.postgresql.org/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm
$ sudo yum -y install postgresql96 postgresql96-devel postgresql96-contrib postgresql96-server
如何在CentOS/RHEL 7/6/5和Fedora 25/24/23上安装PostgreSQL 9.6的方法。
如果不是9.6版本,请将其中的9.6或96部分替换为相应的数字。如果替换不起作用,请各自查找适用版本的安装方法。
如果 PostgreSQL 相关命令的版本不同
由於安裝的是 PostgreSQL 9.6,在這個例子中,相關的命令也應該是 9.6 的版本,但可能出現不一致的情況。這是因為可能已經安裝了舊版本或者其他版本的 PostgreSQL。
为了确认这个,您可以检查psql命令的版本。
$ psql --version
psql (PostgreSQL) 9.2.18
尽管安装了9.6版本,但显示为9.2版本。由于出现这种情况,将来可能会出现各种不便,因此需要进行修正。请执行以下命令,将安装了9.6版本的命令的二进制文件路径添加到环境变量中。
# バージョンが異なる場合のみ
$ echo 'export PATH="/usr/pgsql-9.6/bin:$PATH"' >> ~/.bash_profile
将通道中的路径反映出来。
$ exec -l $SHELL
请再次使用 psql 命令确认版本。请确保安装的 PostgreSQL 的版本一致。
$ psql --version
psql (PostgreSQL) 9.6.5
请确认其他是否也会使用pg_restore工具,以确保版本相同。
$ pg_restore --version
创建Mastodon服务文件
创建启动Mastodon所需的服务文件。将创建以下3个服务。
-
- mastodon-web.service
-
- mastodon-sidekiq.service
- mastodon-streaming.service
我在/etc/systemd/system/下创建了上述的3个服务文件。
[Unit]
Description=mastodon-web
After=network.target
[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="PORT=3000"
ExecStart=/bin/bash -lc 'bundle exec puma -C config/puma.rb'
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
[Unit]
Description=mastodon-sidekiq
After=network.target
[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="RAILS_ENV=production"
Environment="DB_POOL=5"
ExecStart=/bin/bash -lc 'bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push'
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
[Unit]
Description=mastodon-streaming
After=network.target
[Service]
Type=simple
User=mastodon
WorkingDirectory=/home/mastodon/live
Environment="NODE_ENV=production"
Environment="PORT=4000"
ExecStart=/home/mastodon/.ndenv/shims/npm run start
TimeoutSec=15
Restart=always
[Install]
WantedBy=multi-user.target
请根据环境进行以下三项变更。
如果执行用户不是mastodon的情况下。
请将用户的部分改为相应的用户。
如果Mastodon的目录不是/home/mastodon/live的话。
请使用完整路径将”WorkingDirectory”的位置指定为Mastodon目录。
如果 npm 的路径不同的话
如果使用ndenv,就不需要特别担心。但是如果使用其他方式安装Node.js(npm),则需要将路径正确修改。
首先,请确认 npm 的路径。
$ which npm
~/.ndenv/shims/npm
请将 mastodon-streaming.service 的 ExecStart 路径替换为在此处显示的路径。但是,请将 ~ 解释为 /home/用户名。
如果在途中需要更改服务文件的话
使用在这里定义的服务文件启动后,如果后来发现有输入错误等需要更改文件内容时,必须重新加载守护程序。
$ sudo systemctl daemon-reload
艰辛的故事 (Kǔ huà)
这个文件是根据Mastodon官方存储库的生产指南参考而来的,但不知何故,当按照这个指南的服务文件来操作时,会发生错误,导致守护程序无法启动。(严格来说,它会启动,但几秒钟后会出现一个奇怪的错误导致它崩溃)
一边仔细查看错误日志,我一直在努力调查,终于找到了解决方案。
在DigitalOcean上,生产模式似乎无法工作。
当我按照这个方法更改了文件后,它正常运行了。为什么它可以成功,以及为什么它在生产指南的示例中无法正常运行,我不知道,但是我花了几个小时才找到了这个解决方案…
将 PostgreSQL 和 Redis 数据备份和恢复
【重要】必须同时备份 PostgreSQL 和 Redis 数据库,并且备份数据必须是同一时期的。
这是在使用PostgreSQL版本之后最重要的事情。我们将把在Docker中使用的PostgreSQL和Redis数据放在服务器的根目录下。然而,在恢复数据时,如果两者的运行时间不同,就会出现意外问题。我遇到的问题是主页时间轴变空了,没有显示任何内容的情况。
例如,不能同时使用在9月5日进行的PostgreSQL备份数据和在9月6日进行的Redis备份数据。请务必使用在相同时间段内运行的数据。具体来说,正在Docker上运行的PostgreSQL和Redis数据必须一起进行备份。
在 Docker 运行的情况下,恢复 PostgreSQL 数据,经过一段时间后,恢复 Redis 数据。在进行 PostgreSQL 恢复之后再进行 Redis 恢复的过程中,这些数据会被覆盖,因此不再是同时期的数据。
因此,在恢复PostgreSQL和Redis的数据时,必须先停止Mastodon的Docker容器,然后在相同的时间进行恢复。
【重要】关于9月11日之前的备份和恢复
在这篇文章中,介绍了作为 PostgreSQL 备份和还原的推荐方法,即直接复制 Mastodon 目录下的 postgres 和 redis 目录的内容。
然而,這最終成為了一個糟糕的案例。我們通過這種方式進行了mastodon.noraworld.jp的遷移維護,並且在撰寫這篇文章之後,該實例內部出現了一些問題,其中一些用戶帳戶出現了分裂,特定用戶的發布無法流通,不得不面臨無法搜索或發送提及等故障。
通过向Mastodon的核心开发团队咨询,我们确定了这个问题的原因,即数据库中的索引已损坏。由于索引的损坏,记录被添加而无视了账号的用户名和域名不应该完全相同的唯一约束条件,从而导致账号出现了分裂等故障。
参考:我的实例 #4856 的数据库出现问题。
虽然本来不应该发生这样的事情,但是如果直接将在Docker中使用的数据库文件复制,可能会导致这样的问题。因此,不建议使用这种备份方法。同时,已经删除了本文中关于这种方法的说明。请使用后续的说明中介绍的 pg_dump 和 pg_restore 进行备份和还原,而不是直接复制文件来进行备份。
拒绝访问Mastodon
在下面的说明中,将使用pg_dump命令。使用此命令备份PostgreSQL的方法称为“逻辑备份”。逻辑备份必须在PostgreSQL服务器运行时执行。因此,在备份过程中,需要停止对Mastodon的外部访问,以防止数据库被修改而导致数据不一致。
要停止访问,最快的方法是停止 Web 服务器(Nginx),但如果不想停止所有服务,可以在 Mastodon 的 server 上下文中添加 deny all; ,以暂时拒绝对 Mastodon 的所有访问。
server {
server_name マストドンで使用しているドメイン;
+ deny all;
}
添加deny all之后,请确认是否有任何语法错误,并重新加载。
$ sudo nginx -t
$ sudo nginx -s reload
用于PostgreSQL的逻辑备份
如果 Docker 中的数据库没有备份,将进行备份。如果 Mastodon 的 Docker 容器没有启动,则启动它。
$ docker-compose up -d
连接到DB容器。
$ docker exec -it mastodon_db_1 /bin/bash
使用postgres用户登录。
$ su - postgres
我們將進行邏輯備份,並將備份文件命名為mastodon_docker.dump。
$ pg_dump -Fc -U username dbname > mastodon_docker.dump
请在username和dbname中分别填入用户名和数据库名称。要确认用户名和数据库名称,请查看.env.production文件中的DB_USER和DB_NAME。
生成的备份文件被称为自定义归档格式。除了脚本格式和tar格式之外,自定义归档格式具有较小的文件大小,并且还可以在以后转换为脚本格式,因此具有较高的通用性。个人推荐使用自定义归档格式。
参考:逻辑备份(pg_dump和pg_dumpall)
参考:PostgreSQL的备份和恢复方法总结
进行备份后,将从Docker容器中登出。
$ exit
$ exit
将Docker容器中的备份文件移动到服务器根目录下。
$ docker cp mastodon_db_1:/var/lib/postgresql/mastodon_docker.dump ~/backup
Redis的备份。
接下来要备份Redis的数据,连接到Redis容器。
$ docker exec -it mastodon_redis_1 /bin/sh
我正在进行数据备份,但是我认为在连接后的目录(/data)中已经有一个 dump.rdb 文件了。如果存在该文件,则会将其更改为另一个名称。
# dump.rdb が存在する場合
$ mv dump.rdb dump.rdb.old
使用redis-cli命令进行备份。
$ redis-cli save
然后,将会生成一个名为dump.rdb的文件。如果文件已经生成,就从Docker容器中退出登录。
$ exit
和之前一样,将Docker容器中的备份文件移动到服务器根目录下。
$ docker cp mastodon_redis_1:/data/dump.rdb ~/backup
备份 mastodon_docker.dump 和 dump.rdb 后,停止 Docker 容器。
$ docker-compose stop
对 PostgreSQL 进行恢复
如果这是第一次安装PostgreSQL 9.6,您需要进行初始化。如果之前已经使用过PostgreSQL 9.6,则不需要执行初始化,否则会导致错误。
# はじめて PostgreSQL 9.6 を使用する場合
$ sudo /usr/pgsql-9.6/bin/postgresql96-setup initdb
另外,我们需要修改/var/lib/pgsql/9.6/data/pg_hba.conf文件,以便从Mastodon应用程序访问。即使您已经在使用PostgreSQL 9.6,也请仔细确认。在编辑文件时需要root权限。
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
- local all all peer
+ local all all trust
# IPv4 local connections:
- host all all 127.0.0.1/32 ident
+ host all all 127.0.0.1/32 trust
# IPv6 local connections:
- host all all ::1/128 ident
+ host all all ::1/128 trust
参考:PostgreSQL的错误FATAL:用户身份验证失败
请启动 PostgreSQL 9.6 服务器,检查其状态。
$ sudo systemctl start postgresql-9.6
$ systemctl status postgresql-9.6
如果处于活动状态,则已经启动。
将之前备份的文件复制到包含 PostgreSQL 数据的目录中。
$ sudo cp ~/backup/mastodon_docker.dump /var/lib/pgsql
将备份文件的所有权更改为postgres。
$ sudo chown postgres:postgres /var/lib/pgsql/mastodon_docker.dump
登录到postgres用户,并设置为可使用psql执行SQL的状态。
$ sudo -u postgres psql
执行以下的SQL语句。
sql> CREATE USER username CREATEDB;
sql> CREATE DATABASE dbname WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.utf8' LC_CTYPE = 'en_US.utf8';
sql> ALTER DATABASE dbname OWNER TO username;
sql> \q
请将”username”和”dbname”更改为其他名称。
重新使用postgres用户登录。
$ sudo su - postgres
恢复备份文件。
$ pg_restore -U username -C -d dbname mastodon_docker.dump --schema=public
建议:在使用 pg_restore 时不要指定 –table 选项
参考:PostgreSQL:非特权用户使用 pg_dump 和 pg_restore
请更改用户名和数据库名称。
尽管添加了各种选项,但只需按照这个选项执行,可能就不会出现错误。如果 PostgreSQL 的版本在 Docker 内和此处不同,可能会因兼容性问题而导致错误输出。这就是为什么建议安装相同版本的 PostgreSQL。
如果没有发生错误的话,现在就可以恢复Mastodon的数据了。现在从Postgres注销。
$ exit
一旦停止 PostgreSQL 9.6 服务器。
$ sudo systemctl stop postgresql-9.6
Redis 数据恢复
在进行恢复操作之前,如果Redis服务器已经启动,请务必先停止再进行恢复。
$ sudo systemctl stop redis
只需将文件转移即可进行 Redis 的备份恢复,与 PostgreSQL 不同,无需进行恢复命令。
$ sudo cp ~/backup/dump.rdb /var/lib/redis
将所有者更改为Redis。
$ sudo chown redis:redis /var/lib/redis/dump.rdb
我很担心只有这么少,但这已经足够了。很简单对吧。
如果在服务器的根目录下使用了其他应用程序已经在使用Redis的情况下,使用这种方法会导致其他应用程序的数据被删除。有关如何恢复Docker中使用的Mastodon的Redis数据以及在服务器的根目录下已经为其他应用程序使用的Redis数据,请查阅其他文章。
编辑Mastodon的环境配置文件。
由于从Docker迁移到非Docker环境,您需要更改Mastodon的配置文件。具体来说,您需要将REDIS_HOST和DB_HOST更改为localhost。
- REDIS_HOST=redis
+ REDIS_HOST=localhost
- DB_HOST=db
+ DB_HOST=localhost
如果以后由于某种情况需要暂时启动Mastodon Docker容器时,请确保在停止服务器上的PostgreSQL、Redis、mastodon-web、mastodon-sidekiq、mastodon-streaming之后,不要忘记将上述文件替换为Docker环境中的文件。
移民
开始PostgreSQL服务器并执行迁移。
$ sudo systemctl start postgresql-9.6
$ RAILS_ENV=production bundle exec rails db:migrate
$ sudo systemctl stop postgresql-9.6
预编译
如果在Docker中运行,首先要更改public/assets、public/packs和public/system的所有者和所有群组为Docker的拥有者。然后执行预编译。
$ sudo chown -R $(whoami):$(whoami) public/assets public/packs public/system
$ RAILS_ENV=production bundle exec rails assets:precompile
如果以后出现某种情况需要暂时启动Mastodon Docker容器,那么在停止下面的服务器上的PostgreSQL、Redis、mastodon-web、mastodon-sidekiq、mastodon-streaming之后,请务必不要忘记更改public/assets、public/packs、public/system的所有者和所有组。
启动守护程序
如果Mastodon的Docker容器正在运行,则无法启动守护进程,因此如果容器正在运行,则会停止它。
$ docker-compose stop
一旦停止容器后,我们将正式启动服务。
$ sudo systemctl start postgresql-9.6 redis mastodon-web mastodon-sidekiq mastodon-streaming
确认恶魔的状态
我要确认所有的守护程序都已经启动。
$ systemctl status postgresql-9.6 redis mastodon-web mastodon-sidekiq mastodon-streaming
只要所有服务的状态都是”active”,就表示一切正常。
启用守护进程的自动启动
请确认所有的守护进程都已正确启动后,启用设置,使得这些服务在服务器重新启动时自动启动。
$ sudo systemctl enable postgresql-9.6 redis mastodon-web mastodon-sidekiq mastodon-streaming
允许访问Mastodon。
允许访问之前被拒绝的Mastodon。
server {
server_name マストドンで使用しているドメイン;
- deny all;
}
检查是否有句法错误,并重新启动。
$ sudo nginx -t
$ sudo nginx -s reload
请尝试访问网络并确认系统是否正确启动,以及数据是否能够成功恢复。只需确保个人发表的推文、时间线、通知列表、收藏列表、设置、个人介绍、网站描述、图片以及已认证的应用程序列表等所有数据都能够正确读取即可。辛苦了!
续集
删除不需要的 Docker 容器
一旦确认在非Docker环境下正常运行后,就不再需要Mastodon的Docker容器。即使希望再次在Docker上运行,只要数据持久化,随时可以切换回Docker运行。
为了增加可用空间,最好删除未运行的Mastodon Docker容器。您可以使用以下命令删除当前未运行的容器、未使用的镜像和卷。
$ docker system prune -a
使用这个命令,将删除在Mastodon中使用的Docker容器。顺便提一下,我的服务器环境中释放了大约3GB的空间。这相当不错。
几天过去了,说到9月13日的事情,我们将服务器内的所有Web服务从Docker容器迁移到非Docker环境。通过这次经历,我得出结论认为Docker不适用于生产环境,并决定不再在服务器上使用Docker,于是卸载了Docker本身。结果,在删除Mastodon的Docker容器之前,我们总共释放了约15GB的可用空间。总之,Docker似乎非常占用空间。
修改cronjob
如果您在Docker上运行Mastodon,并且定期使用docker或docker-compose命令执行某些任务,那么您需要用不使用Docker的命令来替换它们。
例如
$ docker-compose run --rm web rails mastodon:remove_remote
如果用 cron 命令执行的话,
$ RAILS_ENV=production bundle exec rails mastodon:remove_remote
需要进行更改。此外,需要注意的是,必须附加 RAILS_ENV=production。这是一个容易忽略的点,因为在使用Docker命令时通常会忘记添加。
故障排除
在按照这篇文章的步骤进行时,如果发生错误,请首先参考此处。如果问题仍未解决,请查阅其他文章。
致命错误:用户身份验证失败
在进行迁移或其他与数据库相关的操作时,可能会出现此类错误。
如果发生此错误,请打开/var/lib/pgsql/9.6/data/pg_hba.conf文件,并更改相应的部分。
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
- local all all peer
+ local all all trust
# IPv4 local connections:
- host all all 127.0.0.1/32 ident
+ host all all 127.0.0.1/32 trust
# IPv6 local connections:
- host all all ::1/128 ident
+ host all all ::1/128 trust
我将全部更改为信任。
更改后,重新启动PostgreSQL以使更改生效。
$ sudo systemctl stop postgresql-9.6
$ sudo systemctl start postgresql-9.6
参考:PostgreSQL的错误,用户的身份验证失败导致致命错误。
数据目录不为空!
$ sudo /usr/pgsql-9.6/bin/postgresql96-setup initdb
执行上述命令可能发生的错误是,当试图初始化PostgreSQL时,已经存在数据,无法进行初始化。因此,如果出现此错误,意味着没有必要执行此命令。
如果无法启动PostgreSQL服务器,并且确实需要执行此命令,您需要首先删除或将PostgreSQL的数据备份到其他位置。
$ sudo mv /var/lib/pgsql/9.6/data ~/backup
请在执行此命令之后继续操作。
参考:Postgres在CentOS和Amazon Linux上初始化数据库(initdb)时报错:数据目录不为空![失败]。
错误:无权创建数据库。
我认为你可能不会遇到这个错误。如果确实遇到了这个错误,很可能是因为某些地方搞错了(误解、命令错误、执行顺序错误等),请查看执行过的命令历史记录,确认是否有什么异常之处。
致命错误:角色”用户名”无权登录
数据库的角色将会填入”username”的位置。
这意味着您没有登录权限,就像错误信息所描述的那样。首先,要连接到PostgreSQL。
$ sudo systemctl start postgresql-9.6
$ sudo -u postgres psql
使用以下命令授予权限。
sql> ALTER ROLE "username" WITH LOGIN;
sql> \q
请替换”用户名”。
参考:超级用户无权登录,PostgreSQL:角色无权登录。
对不起,出现了一些问题。
当您启动服务并访问Web时,如果出现此错误页面,请确认以下4个点。
检查一下 Docker 容器是否已经启动。
不确定原因,但是有时在进行non-Docker迁移的某个时间点,即使执行了docker-compose stop来停止,Mastodon的Docker容器会自动重新启动。虽然原因不明,但此时应停止Mastodon的Docker容器。
$ docker-compose stop
你是否忘记修改.env.production文件了?
這是一個常見的錯誤,我們經常不小心忘記。請將 REDIS_HOST 和 DB_HOST 都修改為 localhost。
- REDIS_HOST=redis
+ REDIS_HOST=localhost
- DB_HOST=db
+ DB_HOST=localhost
资产、包装、系统的所有者是否未转移到 Docker?
如果 public/assets 或 public/packs 的所有者和所有组设置为 Docker,则无法读取 CSS 和 JS 文件,导致出现此错误页面。另外,如果无法读取 public/system,则无法读取图像。请更改所有者和所有组以确保可读取。
$ sudo chown -R $(whoami):$(whoami) public/assets public/packs public/system
请确保您没有忘记进行迁移或预编译操作。
如果忘记迁移或预编译,可能会显示这个错误页面。关于迁移,如果在迁移数据库之前已经完成了,则不需要再次进行,但如果感到不安,最好还是为了确保进行一次。
$ RAILS_ENV=production bundle exec rails db:migrate
$ RAILS_ENV=production bundle exec rails assets:precompile
确认以上4个要点后,重新启动PostgreSQL、Redis、mastodon-web、mastodon-sidekiq、mastodon-streaming。
$ sudo systemctl stop postgresql-9.6 redis mastodon-web mastodon-sidekiq mastodon-streaming
$ sudo systemctl start postgresql-9.6 redis mastodon-web mastodon-sidekiq mastodon-streaming
失败历史(额外的)
这次环境迁移的失败是因为我的知识浅薄,导致了各种问题的出现。我将把这个失败经历留作个人的戒备。
1 首次回顾
在标准的Yum存储库中安装了PostgreSQL,结果安装的版本比Docker容器中的版本要旧。在这种情况下,以脚本形式将Docker容器中的PostgreSQL数据进行逻辑备份,并将其还原到服务器根目录下,结果发现由于某些SQL存在兼容性问题,导致了无法恢复一部分用户的收藏夹、已认证的应用程序列表和图片链接引用数据等问题。
第二次
我安装了与Docker内相同版本的PostgreSQL。这次不是通过逻辑备份,而是直接迁移了Docker内使用的PostgreSQL数据文件,并恢复了数据。然而,由于在此过程中使用了Redis的dump文件中的第一个还原版本,导致数据不一致,主页时间线变空了,出现了无法显示任何内容的故障。
第三个回合
为了避免 PostgreSQL 和 Redis 数据不一致的情况,我们迁移了同时使用的数据。然而,由于第二次同样没有进行 PostgreSQL 的逻辑备份而直接迁移了数据文件,导致数据库中的索引损坏,部分用户账户分裂,并且特定用户的戳泪贴流失,无法搜索或发送提及,从而导致了故障。