Update zh-cn translations

This commit is contained in:
CDN 2025-04-06 03:29:30 +08:00
parent 5e2b739ee1
commit a939c23559
Signed by: CDN
GPG key ID: 0C656827F9F80080
168 changed files with 36955 additions and 1406 deletions

View file

@ -1,55 +1,55 @@
---
title: 备份你的服务器
description: 设置日常备份(可选,但并非如此
description: 设置定期备份(可选,但实际上很必要
menu:
docs:
weight: 80
parent: admin
---
对于任何真实世界用途来说你都应该保证日常备份Mastodon服务器。
对于所有实际使用的场景,你都应确保定期备份你的 Mastodon 服务器。
## 概 {#overview}
## 概 {#overview}
你所需要备份的东西,按重要程度排序
需要备份的内容按重要程度排序如下
1. PostgreSQL 数据库
2. `.env.production` 文件或等效文件的应用密钥
2. 来自 `.env.production` 文件或等效文件的应用密钥
3. 用户上传的文件
4. Redis 数据库
## 故障模式 {#failure}
## 故障类别 {#failure}
人们通常要应对两种类型故障:硬件故障,诸如磁盘上数据损坏;以及人为软件故障,诸如误删特定文件。本文档中,仅考虑前一种类型。
人们通常会防范两种类型的故障:硬件故障,如磁盘数据损坏;以及人为和软件错误,如错误删除某特定数据。在本文档中,我们仅考虑前一种类型。
丢失PostgreSQL数据库那一切都完了。Mastodon将所有重要数据存储于PostgreSQL数据库中。如果数据库消失那你服务器上所有的帐户、所有的嘟文、所有关注者都将随之消失
Mastodon 将所有最重要的数据存储在 PostgreSQL 数据库中。PostgreSQL 数据库的丢失将导致服务器完全故障,包括所有账户、嘟文与关注者信息
如果你丢失了应用密钥,对你的用户而言Mastodon的某些功能将停止工作。你服务器上的用户将被登出双因子认证2FA将不可用Web Push API订阅将停止工作。
如果你丢失了应用密钥,Mastodon 的某些功能将停止为用户工作,用户将被登出,双因素认证将不可用,且 Web Push API 订阅将停止工作。
如果丢失了用户上传的文件,你将丢失头像、横幅、媒体附件但Mastodon*仍会*继续工作。
如果丢失了用户上传的文件,你将丢失头像、资料卡横幅背景图和媒体附件,但 Mastodon 在未来仍能正常工作。
丢失Redis数据库几乎是无害的唯一不可逆的数据是Sidekiq队列及之前失败任务的重试计划。主页与列表时间流虽然存储于Redis但它们可以使用tootctl再生成。
丢失 Redis 数据库几乎无害:唯一不可恢复的数据是 Sidekiq 队列的内容和先前失败任务的计划重试时间。主页和列表信息流存储在 Redis 中,但可以通过 tootctl 重新生成。
最好的备份是所谓的异地备份即与Mastodon自身不在同一台计算机上存储的备份。如果你托管的服务器起火了硬盘爆炸了存储于同一硬件备份将不可用
最好的备份是被称为异地备份的备份模式,即不存储在与 Mastodon 服务器本身相同的机器上的备份。如果你的服务器着火并且硬盘驱动器爆炸,存储在同一硬盘上的备份将没有太大用处
## 备份应用密钥 {#env}
应用密钥是最容易备份的,因为它们是不变的。你只需要将 `.env.production` 存储在安全的地方就可以了
应用密钥是最容易备份的,因为它们从不变化。你只需将 `.env.production` 存储在安全的地方即可
## 备份 PostgreSQL {#postgresql}
突然断电、硬盘故障、错误迁移数库库schema都会致使数据损坏。由于以上原因推荐偶尔使用 `pg_dump``pg_dumpall` 备份数据库
PostgreSQL 面临断电、硬盘驱动器故障与错误的架构迁移带来的数据损坏风险。因此,建议偶尔使用 `pg_dump``pg_dumpall` 进行备份。
如果要求高可用性可以使用热流拷贝hot streaming replication使第二台PostgreSQL服务器始终具有最新数据并做好另一台服务器出现故障切换至此的准备
对于高可用配置可以使用热数据流式复制来拥有一个数据始终最新的第二PostgreSQL服务器以便在另一服务器宕机时随时切换
## 备份用户上传的文件 {#media}
如果你使用外部对象存储诸如Amazon S3、Google Cloud 或 Wasabi你无需为怎么备份它们而担心。各自的公司将负责处理硬件故障。
如果你使用外部对象存储提供商如亚马逊S3、谷歌云或 Wasabi则无需担心备份这些文件。相应公司负责处理硬件故障。
如果你使用本地文件存储,复制体积巨大的 `public/system` 目录(默认存储上传文件的地方)
如果你使用是本地文件存储,那么你需要自行对 `public/system` 这个大目录进行备份,该目录是上传文件的默认存储位置
## 备份 Redis {#redis}
备份Redis是很容易的。Redis会定期将数据写入`/var/lib/redis/dump.rdb`文件,你只需要复制这个文件就可以了
备份 Redis 很容易。Redis 定期写入 `/var/lib/redis/dump.rdb`,这是你唯一需要复制的文件
{{< translation-status-zh-cn raw_title="Backing up your server" raw_link="/admin/backups/" last_tranlation_time="2020-05-06" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
{{< translation-status-zh-cn raw_title="Backing up your server" raw_link="/admin/backups/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,250 @@
---
title: 配置全文搜索
description: 设置 Elasticsearch 以搜索嘟文(包括创建的嘟文、喜欢的嘟文和被提及的嘟文)、可公开索引的嘟文与账号
aliases:
- /admin/optional/elasticsearch
menu:
docs:
weight: 40
parent: admin
---
当 Elasticsearch 可用时Mastodon 支持全文搜索。强烈建议配置此功能。
Mastodon 的全文搜索允许已登录用户查找以下内容:
- 选择在搜索结果中显示的账号发布的公开嘟文
- 自己创建的嘟文
- 提及自己的嘟文
- 自己喜欢的嘟文
- 自己收藏的嘟文
- 账号(显示名称、用户名和简介)
全文搜索有意不允许在整个数据库中搜索任意字符串。
## 安装 Elasticsearch {#install}
{{< hint style="info" >}}
Mastodon 经过测试与 Elasticsearch 7 版本兼容。它理论上也支持 OpenSearch 以及 Elasticsearch 6 和 8 版本,但这些设置不受官方支持。
{{< /hint >}}
Elasticsearch 需要 Java 运行环境。如果你尚未安装 Java请立即进行安装。假设你以 `root` 用户身份登录:
```bash
apt install openjdk-17-jre-headless
```
将 Elasticsearch 官方仓库添加到 apt
```bash
wget -O /usr/share/keyrings/elasticsearch.asc https://artifacts.elastic.co/GPG-KEY-elasticsearch
echo "deb [signed-by=/usr/share/keyrings/elasticsearch.asc] https://artifacts.elastic.co/packages/7.x/apt stable main" > /etc/apt/sources.list.d/elastic-7.x.list
```
现在你可以安装 Elasticsearch
```bash
apt update
apt install elasticsearch
```
{{< hint style="warning" >}}
**安全警告:** 默认情况下, Elasticsearch 应仅绑定到 `localhost`,即无法从外部网络访问。你可以通过查看 `/etc/elasticsearch/elasticsearch.yml` 中的 `network.host` 来检查 Elasticsearch 绑定的地址。请考虑到任何能够访问 Elasticsearch 的人都可以访问和修改其中的任何数据,因为没有认证层。所以确保访问安全非常重要。建议使用防火墙,只开放 22、 80 和 443 端口,如[主安装说明](../../prerequisites/#install-a-firewall-and-only-whitelist-ssh-http-and-https-ports)中所述。如果你有多主机设置,你必须了解如何保护内部流量安全。
{{< /hint >}}
启动 Elasticsearch
```bash
systemctl daemon-reload
systemctl enable --now elasticsearch
```
## 配置 Mastodon {#config}
编辑 `.env.production` 以添加以下变量:
```bash
ES_ENABLED=true
ES_HOST=localhost
ES_PORT=9200
ES_PRESET= # single_node_cluster, small_cluster或large_cluster
# ES_USER=
# ES_PASS=
```
_注意_如果使用 TLS请在主机名前加上 `https://`。例如:`https://elastic.example.com`
### 选择正确的预设
`ES_PRESET` 的值取决于你的 Elasticsearch 规模,它将用于为你的索引设置最适合你设置的分片和副本数量:
- `single_node_cluster` 如果你的 Elasticsearch 集群中只有一个节点。索引将配置为无副本
- `small_cluster` 如果你的集群少于 6 个节点。索引将配置为单副本
- `large_cluster` 如果你的集群有 6 个或更多节点。索引将较之 `small_cluster` 配置更多的分片,以便它们可以分布在更多节点上
如果你在同一台机器上有多个 Mastodon 服务器,并且计划为所有这些服务器使用相同的 Elasticsearch 实例,请确保它们都在配置中设置了唯一的 `REDIS_NAMESPACE`,以区分索引。如果你需要覆盖 Elasticsearch 索引的前缀,可以直接设置 `ES_PREFIX`
### 安全性
默认情况下Elasticsearch 不处理任何认证,所有请求都以完全管理员权限进行。我们强烈建议你在集群上配置 Elasticsearch 安全功能。
要进行配置,请参考[官方文档](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-minimal-setup.html)。它将指导你进行以下操作:
- 启用安全功能(`xpack.security.enabled: true`
- 为内置用户创建密码
完成后,你可以创建自定义用户组供 Mastodon 连接。
例如(可以参考此段命令并使用你的 Elastic 管理员密码):
```sh
curl -X POST -u elastic:admin_password "localhost:9200/_security/role/mastodon_full_access?pretty" -H 'Content-Type: application/json' -d'
{
"cluster": ["monitor"],
"indices": [{
"names": ["*"],
"privileges": ["read", "monitor", "write", "manage"]
}]
}
'
```
[Elasticsearch用户组创建文档](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-put-role.html)
创建用户组后你可以为Mastodon服务器创建用户并为其分配用户组。
例如请调整此片段以使用你的Elastic管理员密码并自定义你新`mastodon`用户的密码):
```sh
curl -X POST -u elastic:admin_password "localhost:9200/_security/user/mastodon?pretty" -H 'Content-Type: application/json' -d'
{
"password" : "l0ng-r4nd0m-p@ssw0rd",
"roles" : ["mastodon_full_access"]
}
'
```
[Elasticsearch用户创建文档](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/security-api-put-user.html)
完成后,你需要配置 Mastodon 使用新创建用户的凭据。
然后在 `.env.production` 中,调整你的配置:
```bash
ES_USER=mastodon
ES_PASS=l0ng-r4nd0m-p@ssw0rd
```
设置完成,你的 Elasticsearch 实例应该更安全了!
### 填充索引
保存新配置后,重启 Mastodon 进程使其生效:
```bash
systemctl restart mastodon-sidekiq
systemctl reload mastodon-web
```
现在是时候创建 Elasticsearch 索引并填充数据了:
```bash
su - mastodon
cd live
RAILS_ENV=production bin/tootctl search deploy
```
{{< hint style="info" >}}
创建 Elasticsearch 索引可能需要 JVMJava 虚拟机)提供的更多内存。如果 Elasticsearch 在创建索引时崩溃,请尝试分配更多内存。
1. 在 `/etc/elasticsearch/jvm.options.d/` 目录下创建并打开一个文件(例如:`nano /etc/elasticsearch/jvm.options.d/ram.options`
2. 添加以下文本并根据需求编辑分配的内存。根据经验, Elasticsearch 应使用你可用内存的25%-50%。请不要分配超过可用内存的内存量。
```
# Xms表示总堆空间的初始大小
# Xmx表示总堆空间的最大大小
# 两个值应该相同
-Xms2048m
-Xmx2048m
```
3. 保存文件。
4. 使用 `systemctl restart elasticsearch` 重启 Elasticsearch。
5. 重试创建 Elasticsearch 索引。如果 Elasticsearch 仍然崩溃,请尝试设置更高的数值。
{{< /hint >}}
## 其他语言的搜索优化
### 中文搜索优化 {#chinese-search-optimization}
标准分析器是 Elasticsearch 的默认分析器,但对于中文等某些语言来说,它可能不是最佳选择。要增强搜索体验,请考虑安装特定语言的分析器。在 Elasticsearch 中创建索引之前,请确保安装以下扩展:
- [elasticsearch-analysis-ik](https://github.com/medcl/elasticsearch-analysis-ik)
- [elasticsearch-analysis-stconvert](https://github.com/medcl/elasticsearch-analysis-stconvert)
然后按如下方式修改 Mastodon 的索引定义:
```diff
diff --git a/app/chewy/accounts_index.rb b/app/chewy/accounts_index.rb
--- a/app/chewy/accounts_index.rb
+++ b/app/chewy/accounts_index.rb
@@ -4,7 +4,7 @@ class AccountsIndex < Chewy::Index
settings index: { refresh_interval: '5m' }, analysis: {
analyzer: {
content: {
- tokenizer: 'whitespace',
+ tokenizer: 'ik_max_word',
filter: %w(lowercase asciifolding cjk_width),
},
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
--- a/app/chewy/statuses_index.rb
+++ b/app/chewy/statuses_index.rb
@@ -16,9 +16,17 @@ class StatusesIndex < Chewy::Index
language: 'possessive_english',
},
},
+ char_filter: {
+ tsconvert: {
+ type: 'stconvert',
+ keep_both: false,
+ delimiter: '#',
+ convert_type: 't2s',
+ },
+ },
analyzer: {
content: {
- tokenizer: 'uax_url_email',
+ tokenizer: 'ik_max_word',
filter: %w(
english_possessive_stemmer
lowercase
@@ -27,6 +35,7 @@ class StatusesIndex < Chewy::Index
english_stop
english_stemmer
),
+ char_filter: %w(tsconvert),
},
},
}
diff --git a/app/chewy/tags_index.rb b/app/chewy/tags_index.rb
--- a/app/chewy/tags_index.rb
+++ b/app/chewy/tags_index.rb
@@ -2,10 +2,19 @@
class TagsIndex < Chewy::Index
settings index: { refresh_interval: '15m' }, analysis: {
+ char_filter: {
+ tsconvert: {
+ type: 'stconvert',
+ keep_both: false,
+ delimiter: '#',
+ convert_type: 't2s',
+ },
+ },
analyzer: {
content: {
- tokenizer: 'keyword',
+ tokenizer: 'ik_max_word',
filter: %w(lowercase asciifolding cjk_width),
+ char_filter: %w(tsconvert),
},
edge_ngram: {
```
{{< translation-status-zh-cn raw_title="Configuring full-text search" raw_link="/admin/elasticsearch/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,6 +1,6 @@
---
title: 从源安装
description: 创建你自己的Mastodon站点的教学指献
title: 从源代码安装
description: 创建你自己的 Mastodon 站点的教程
menu:
docs:
weight: 20
@ -9,105 +9,84 @@ menu:
## 前提条件 {#pre-requisites}
* 一台你有root访问权限的运行 **Ubuntu 18.04** 的机器
* 一个用于Mastodon站点的**域名**(或一个子域名),例如:`example.com`
* 一个电子邮件发送服务提供商,或其他**SMTP服务器**
* 一台运行 **Ubuntu 24.04****Debian 12** 的机器你需要拥有root访问权限
* 一个用于 Mastodon 站点的**域名**(或子域名),例如 `example.com`
* 一个电子邮件发送服务或其他 **SMTP 服务器**
你需要使用root用户运行命令。如果你现在不是root用户请切换至root用户
在以下示例中,我们将使用 `example.com` 作为域名。请记得在运行任何命令前将其替换为你自己的域名。
### 软件仓库 {#system-repositories}
你将以 root 身份运行命令。如果你还不是 root 用户,请切换到 root`sudo -i`
首先确保已经安装curl
### 系统存储库 {#system-repositories}
首先确保已安装 curl、 wget、 gnupg、 apt-transport-https、 lsb-release 和 ca-certificates
```bash
apt install -y curl wget gnupg apt-transport-https lsb-release ca-certificates
```
#### Node.js {#node-js}
```bash
curl -sL https://deb.nodesource.com/setup_12.x | bash -
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list
```
#### Yarn {#yarn}
#### PostgreSQL {#postgresql}
```bash
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
wget -O /usr/share/keyrings/postgresql.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc
echo "deb [signed-by=/usr/share/keyrings/postgresql.asc] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/postgresql.list
```
### 软件包 {#system-packages}
### 系统软件包 {#system-packages}
```bash
apt update
apt install -y \
imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \
g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \
imagemagick ffmpeg libvips-tools libpq-dev libxml2-dev libxslt1-dev file git-core \
g++ libprotobuf-dev protobuf-compiler pkg-config gcc autoconf \
bison build-essential libssl-dev libyaml-dev libreadline6-dev \
zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev \
nginx redis-server redis-tools postgresql postgresql-contrib \
certbot python-certbot-nginx yarn libidn11-dev libicu-dev libjemalloc-dev
zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev \
nginx nodejs redis-server redis-tools postgresql postgresql-contrib \
certbot python3-certbot-nginx libidn11-dev libicu-dev libjemalloc-dev
```
### 安装 Ruby {#installing-ruby}
#### Yarn {#yarn}
因为使用 rbenv 可以更容易的获得正确的版本并在新版本发布后进行更新,我们将使用 rbenv 来管理Ruby版本。rbenv 必须安装在单个Linux用户中因此我们首先需要使用以下命令创建一个Mastodon用户
启用`corepack`,以便自动安装正确版本的`yarn`
```bash
adduser --disabled-login mastodon
corepack enable
```
切换到mastodon用户
### 创建 `mastodon` 用户 {#creating-the-mastodon-user}
执行以下命令,创建用于运行 Mastodon 的用户:
```bash
su - mastodon
```
执行以下步骤安装 rbenv 和 rbenv-build
```bash
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
cd ~/.rbenv && src/configure && make -C src
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec bash
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
```
上述操作完成,我们便可以安装正确的 Ruby 版本:
```bash
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install 2.6.6
rbenv global 2.6.6
```
我们同样需要安装 bundler
```bash
gem install bundler --no-document
```
返回root用户
```bash
exit
adduser --disabled-password mastodon
```
## 配置 {#setup}
### 配置 PostgreSQL {#setting-up-postgresql}
#### 性能调优(可选) {#performance-configuration-optional}
#### 性能配置(可选) {#performance-configuration-optional}
了优化性能,你可以使用 [pgTune](https://pgtune.leopard.in.ua/#/) 生成一个合适的配置文件。编辑 `/etc/postgresql/9.6/main/postgresql.conf` 中的相应数值并使用 `systemctl restart postgresql` 命令重启 PostgreSQL
为获得最佳性能,你可以使用 [pgTune](https://pgtune.leopard.in.ua/#/) 生成适当的配置,并在使用 `systemctl restart postgresql` 重启 PostgreSQL 之前编辑 `/etc/postgresql/17/main/postgresql.conf` 中的值。
#### 创建户 {#creating-a-user}
#### 创建用户 {#creating-a-user}
你需创建一个供Mastodon使用的PostgreSQL帐户。创建一个使用“ident”认证方式的帐户是最容易的配置方法即PostgreSQL帐户不需要独立的密码并由同名Linux用户使用。
你需要创建一个供 Mastodon 使用的 PostgreSQL 用户。在简单配置中,最简单的方法是使用 "ident" 认证,即 PostgreSQL 用户没有单独的密码,可以由具有相同用户名的 Linux 用户使用。
打开控制台
打开命令行:
```bash
sudo -u postgres psql
```
控制台中执行:
在命令行中执行:
```sql
CREATE USER mastodon CREATEDB;
@ -116,9 +95,9 @@ CREATE USER mastodon CREATEDB;
完成!
### 置 Mastodon {#setting-up-mastodon}
### 置 Mastodon {#setting-up-mastodon}
现在该下载Mastodon代码了。切换至mastodon用户:
现在是下载 Mastodon 代码的时候了。切换到 mastodon 用户:
```bash
su - mastodon
@ -126,111 +105,140 @@ su - mastodon
#### 检出代码 {#checking-out-the-code}
使用git下载最新稳定版Mastodon
使用 git 下载 Mastodon 的最新稳定版本
```bash
git clone https://github.com/mastodon/mastodon.git live && cd live
git checkout $(git tag -l | grep -v 'rc[0-9]*$' | sort -V | tail -n 1)
git checkout $(git tag -l | grep '^v[0-9.]*$' | sort -V | tail -n 1)
```
#### 安装依赖 {#installing-the-last-dependencies}
#### 安装 Ruby {#installing-ruby}
现在安装Ruby和JavaScript依赖
我们将使用 rbenv 来管理 Ruby 版本,因为它简化了获取正确版本和在新版本可用时进行更新的过程。
安装 rbenv 和 ruby-build
```bash
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec bash
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
```
完成这些后我们可以安装正确的Ruby版本
```bash
RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install
```
#### 安装最后的依赖项 {#installing-the-last-dependencies}
现在安装 Ruby 和 JavaScript 依赖项:
```bash
bundle config deployment 'true'
bundle config without 'development test'
bundle install -j$(getconf _NPROCESSORS_ONLN)
yarn install --pure-lockfile
yarn install
```
{{< hint style="info" >}}
两个`bundle config`命令仅仅第一次安装依赖时需要。如果你之后进行升级或重安装依赖,只需要`bundle install`就够了。
仅在首次安装依赖项时需要执行两个 `bundle config` 命令。如果你之后要更新或重新安装依赖项,只需执行 `bundle install` 就足够了。
{{< /hint >}}
#### 生成配置文件 {#generating-a-configuration}
#### 生成配置 {#generating-a-configuration}
运行交互式安装向导:
运行交互式设置向导:
```bash
RAILS_ENV=production bundle exec rake mastodon:setup
RAILS_ENV=production bin/rails mastodon:setup
```
将:
将:
* 创建一个配置文件
* 预编译静态文件
* 创建数据库schema
* 运行资源预编译
* 创建数据库架构
配置文件被保存在`.env.production`。如果你愿意的话,你可以查看并编辑这个文件。请参阅[配置文件的文档]({{< relref "config" >}})。
配置文件保存为 `.env.production`。你可以查看并按照喜好编辑它。请参考[配置文档]({{< relref "config" >}})。
你已经完成需使用mastodon用户进行的操作请切换回root用户:
现在你已完成 mastodon 用户的操作,切回 root 用户:
```bash
exit
```
### 配置 nginx {#setting-up-nginx}
### 获取SSL证书 {#acquiring-a-ssl-certificate}
从Mastodon目录复制配置文件模版到nginx
我们将使用 Let's Encrypt 获取免费的 SSL 证书:
```bash
certbot certonly --nginx -d example.com
```
这将获取证书并将其保存在 `/etc/letsencrypt/live/example.com/` 目录下。
### 设置nginx {#setting-up-nginx}
从 Mastodon 目录复制 nginx 的配置模板:
```bash
cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon
ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon
rm /etc/nginx/sites-enabled/default
```
编辑 `/etc/nginx/sites-available/mastodon`
然后编辑 `/etc/nginx/sites-available/mastodon`
1. 替换 `example.com` 为你自己的域名
2. 启用 `ssl_certificate``ssl_certificate_key` 这两行,并把它们替换成如下两行(如果你使用自己的证书的话则可以忽略这一步)
1. `example.com` 替换为你自己的域名
2. 取消注释 `ssl_certificate``ssl_certificate_key`(如果你使用自己的证书,请忽略此步骤):
```
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
```
```
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;;
```
3. 你还可以根据自己的需求做出其它的一些调整。
3. 进行你可能需要的任何其他调整。
重载 nginx 以使变更生效:
### 获取SSL证书 {#acquiring-a-ssl-certificate}
我们将使用 Lets Encrypt 获取一个免费的SSL证书
允许其他用户遍历 mastodon 用户的主目录,以便 nginx 的 `www-data` 用户可以访问资源文件:
```bash
certbot --nginx -d example.com
chmod o+x /home/mastodon
```
这个命令将获取一个证书,自动更新 `/etc/nginx/sites-available/mastodon` 以使用新证书并重载nginx以使变更生效。
现在你应该能够通过浏览器访问你的域名然后看到一只大象锤击电脑屏幕的错误页面。这是因为我们还没有启动Mastodon进程。
### 配置 systemd 服务 {#setting-up-systemd-services}
从Mastodon目录复制systemd服务模版
重启 nginx 使更改生效:
```bash
systemctl restart nginx
```
此时,你应该能够在浏览器中访问你的域名,看到大象撞击电脑屏幕的错误页面。这是因为我们还没有启动 Mastodon 进程。
### 设置 systemd 服务 {#setting-up-systemd-services}
从 Mastodon 目录复制 systemd 服务模板:
```sh
cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
```
然后修改以下文件,以保证用户名与路径是正确的:
如果你修改了默认设置,请检查用户名和路径是否正确
* `/etc/systemd/system/mastodon-web.service`
* `/etc/systemd/system/mastodon-sidekiq.service`
* `/etc/systemd/system/mastodon-streaming.service`
最后启动新systemd服务并将该服务设为开机自动激活
```bash
systemctl daemon-reload
systemctl start mastodon-web mastodon-sidekiq mastodon-streaming
systemctl enable mastodon-*
```sh
$EDITOR /etc/systemd/system/mastodon-*.service
```
他们将在开机启动时自动开始运行。
最后,启动并启用新的 systemd 服务:
```sh
systemctl daemon-reload
systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming
```
Mastodon 服务现在将在开机时自动启动。
{{< hint style="success" >}}
**欢呼吧!你现在可以从浏览器中访问你的域名了!**
**太好了!以上就是安装 Mastodon 的全部步骤。现在你可以在浏览器中访问你的站点了!**
{{< /hint >}}
{{< translation-status-zh-cn raw_title="Installing from source" raw_link="/admin/install/" last_tranlation_time="2020-05-04" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
{{< translation-status-zh-cn raw_title="Installing from source" raw_link="/admin/install/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,95 +1,154 @@
---
title: 迁移到新机器
description: 在不损失任何东西的情况下把你的Mastodon复制安装至新的服务器上
description: 将你的 Mastodon 站点无损复制到新服务器
menu:
docs:
weight: 90
parent: admin
---
有时出于各种原因你需要将你的Mastodon实例从一台服务器迁移至另一台。幸运的是这个过程并不太困解虽然这可能导致一段时间的下线
出于各种原因,你可能希望将 Mastodon 实例从一台服务器迁移到另一台。幸运的是,这个过程并不太困难,尽管可能会导致一些停机时间
{{< hint style="info" >}}
篇指南基于Ubuntu Server编写根据其他设置的不同你的过程可能会有变化
指南主要针对 Ubuntu Server 编写;对于其他配置环境,你的实际体验可能有所不同
{{< /hint >}}
## 基本步骤 {#basic-steps}
1. 依照[产品指南]({{< relref "install" >}})安装新的Mastodon服务器切记不要运行 `mastodon:setup`)。
2. 停止旧服务器上的Mastodon`systemctl stop 'mastodon-*.service'`)。
3. 依照如下指示导出并导入PostgreSQL数据库。
4. 依照如下指示,复制 `system/` 目录下文件。注意如果你使用S3存储你可以跳过此步
1. 使用[生产环境配置指南]({{< relref "install" >}})设置新的 Mastodon 服务器(但不要运行`mastodon:setup`只保持PostgreSQL服务运行)。
2. 停止旧服务器上的 Mastodon 服务(例如`systemctl stop 'mastodon-*.service'`)。
3. 使用下面的说明导出和加载 PostgreSQL 数据库。
4. 使用下面的说明复制 `system/` 文件。(注意:如果你使用 S3可以跳过此步骤。
5. 复制 `.env.production` 文件。
6. 运行 `RAILS_ENV=production bundle exec rails assets:precompile` 编译 Mastodon。
7. 运行 `RAILS_ENV=production ./bin/tootctl feeds build` 重新构建每个用户的主页时间流。
8. 启动新服务器上的Mastodon。
9. 更新DNS设置将其指向新服务器。
10. 更新或复制你的Nginx设置如果必要的话可重获取LetsEncrypt证书。
11. 享受你的新服务器!
6. 保存 Redis 数据库,停止新旧机器上的 Redis 服务,并将 Redis 数据库从 `/var/lib/redis/` 复制到新服务器。
7. 运行 `RAILS_ENV=production bundle exec rails assets:precompile` 编译 Mastodon。
8. 在新服务器上启动 Mastodon 和 Redis。
9. 运行 `RAILS_ENV=production ./bin/tootctl feeds build` 为每个用户重建主时间线。
10. 运行 `RAILS_ENV=production ./bin/tootctl search deploy` 重建 Elasticsearch 索引(注意:如果你不使用 Elasticsearch可以跳过此步骤。
11. 更新 DNS 设置,指向新服务器。
12. 更新或复制 Nginx 配置,并根据需要重新运行 LetsEncrypt。
13. 享受你的新服务器!
## 详细步骤 {#detailed-steps}
### 什么数据需要被迁移 {#what-data-needs-to-be-migrated}
### 停止 Mastodon 服务
你必须需要复制如下内容:
```bash
systemctl stop 'mastodon-*.service'
```
* `~/live/public/system`目录里面包含了用户上传的图片与视频如果使用S3可跳过此步
* PostgreSQL数据库使用[pg_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html)
* `~/live/.env.production`文件,里面包含了服务器配置与密钥
### 需要迁移哪些数据 {#what-data-needs-to-be-migrated}
不太重要的部分,为了方便起见,你也可以复制如下内容:
总体而言,你需要复制以下内容:
* nginx配置文件位于`/etc/nginx/sites-available/default`
* systemd配置文件`/etc/systemd/system/mastodon-*.service`),里面可能包括一些你服务器的调优与个性化
* PgBouncer配置文件位于 `/etc/pgbouncer` 如果你使用PgBouncer的话
* `~/live/public/system` 目录,该目录包含用户上传的图片和视频(如果使用 S3则不需要
* PostgreSQL 数据库(使用 [pg_dump](https://www.postgresql.org/docs/9.1/static/backup-dump.html)
* `~/live/.env.production` 文件,其中包含服务器配置和密钥
* `/var/lib/redis/` 目录中的 Redis 数据库,其中包含未处理的 Sidekiq 任务。
### 导出并导入PostgreSQL数据库 {#dump-and-load-postgresql}
以下内容不太重要,但为方便起见,你可能仍然想要复制:
不要运行`mastodon:setup`,而是创建一个名为`template0`的空白PostgreSQL数据库当导入PostgreSQL导出文件时这是很有用的参见[pg_dump文档](https://www.postgresql.org/docs/9.1/static/backup-dump.html#BACKUP-DUMP-RESTORE))。
* nginx 配置(位于 `/etc/nginx/sites-available/mastodon`
* 域名的 SSL 证书(若使用 LetsEncrypt应位于 `/etc/letsencrypt/live/`
* systemd 配置文件(`/etc/systemd/system/mastodon-*.service`),其中可能包含你的服务器调整和自定义
* `/etc/pgbouncer` 下的 PgBouncer 配置(如果你使用它)
在你的旧系统,使用`mastodon`用户运行如下命令:
### 导出与导入 PostgreSQL {#dump-and-load-postgresql}
我们不运行 `mastodon:setup`,而是使用 `template0` 数据库创建一个空的 PostgreSQL 数据库(这在还原 PostgreSQL 转储文件时很有用,[如 pg_dump 文档所述](https://www.postgresql.org/docs/9.1/static/backup-dump.html#BACKUP-DUMP-RESTORE))。
如果你的 PostgreSQL 用户使用密码,为方便起见,你可能希望在新系统上配置 `mastodon` 用户使用与旧系统相同的密码:
```bash
sudo -u postgres psql
ALTER USER mastodon WITH PASSWORD 'YOUR_PASSWORD';
\q
```
在旧系统上以 `mastodon` 用户身份运行:
```bash
pg_dump -Fc mastodon_production -f backup.dump
```
使用 `rsync``scp` 复制 `backup.dump` 文件。然后在新系统,使用`mastodon`帐户创建一个空数据库:
使用 `rsync``scp` 复制 `backup.dump` 文件。然后在新系统上,以 `mastodon` 用户身份创建一个空数据库:
```bash
createdb -T template0 mastodon_production
```
然后导入它:
然后导入它(将 `-j#` 中的 `#` 替换为系统中的 CPU 数量以提高还原性能)
```bash
pg_restore -U mastodon -n public --no-owner --role=mastodon \
pg_restore -Fc -j# -U mastodon -n public --no-owner --role=mastodon \
-d mastodon_production backup.dump
```
注意:如果新服务器上的帐户名不是`mastodon`,你应当修改上面命令中 `-U` **和** `--role` 参数。两台服务器的用户名不同也可以。)
请注意,如果新服务器上的用户名不是 `mastodon`,你应该更改上面的 `-U``--role` 值。两个服务器之间可以使用不同的用户名。)
### 复制文件 {#copy-files}
本操作可能花费一些时间,若你希望避免不必要重复制,建议使用`rsync`。在你的旧机器上,使用`mastodon`用户,运行:
这可能需要一些时间,为避免不必要的重复复制,建议使用 `rsync`。在旧机器上,以 `mastodon` 用户身份运行:
```bash
rsync -avz ~/live/public/system/ mastodon@example.com:~/live/public/system/
```
如果旧服务器上任何文件有改动,你需要重运行此命令。
如果旧服务器上的任何文件发生更改,你需要重新运行此命令。
同样需要复制`.env.production`文件,该文件内含密钥。
还应该复制 `.env.production` 文件,其中包含密钥。
可选的你可以复制nginx、systemd、pgbouncer配置文件或者从头开始重写它们。
在新机器上,确保 Redis 未运行,否则它可能会覆盖你尝试还原的转储文件。以 `root` 用户身份运行:
```bash
systemctl stop redis-server.service
```
现在复制你的 Redis 数据库(根据需要调整 Redis 数据库的位置)。在旧机器上,以 `root` 用户身份运行:
```bash
redis-cli SAVE
systemctl stop redis-server.service
rsync -avz /var/lib/redis/ root@example.com:/var/lib/redis
```
作为可选操作,你可以复制 nginx、systemd 和 PgBouncer 配置文件,或者从头重写它们。
### 迁移期间 {#during-migration}
你可以编辑旧机器上的`~/live/public/500.html`页面,如果你希望展示一个优雅的错误信息,让现有用户知晓正在进行迁移。
你可以编辑旧机器上的 `~/live/public/500.html` 页面,以显示一条友好的错误消息,让现有用户知道迁移正在进行中
你也应该提前一天将DNS TTL设置为较小数值30-60分钟。这样当你把DNS指向新IP后新纪录可以很快扩散开来。
可能还想在提前一天将 DNS TTL 设置为较小的值30-60分钟这样一旦你将其指向新 IP 地址DNS 就可以快速传播
### 迁移后 {#after-migrating}
你可以使用[whatsmydns.net](https://whatsmydns.net/)来查看DNS扩散的过程。为了跳过这个过程你可以修改你自己的`/etc/hosts`文件,将其指向你的新服务器,这样你可以尽早开始使用新服务器。
以mastodon用户身份运行以下命令
{{< translation-status-zh-cn raw_title="Migrating to a new machine" raw_link="/admin/migrating/" last_tranlation_time="2020-05-06" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
```bash
RAILS_ENV=production bundle exec rails assets:precompile
```
现在以 root 用户身份运行以下命令:
```bash
systemctl daemon-reload
systemctl start redis-server
systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming
systemctl restart nginx
```
一旦服务器重新上线,你可以为用户重建主页时间线(这可能需要很长时间,取决于用户数量。)
```bash
RAILS_ENV=production ./bin/tootctl feeds build
```
如果你使用 Elasticsearch请运行以下命令重建索引这可能需要很长时间取决于你拥有的状态数量。
```bash
RAILS_ENV=production ./bin/tootctl search deploy
```
你可以查看 [whatsmydns.net](https://whatsmydns.net/) 以了解 DNS 传播的进度。要加速这个过程,你可以编辑自己的 `/etc/hosts` 文件,指向新服务器,这样你就可以提前开始使用它。
{{< translation-status-zh-cn raw_title="Migrating to a new machine" raw_link="/admin/migrating/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,76 +1,320 @@
---
title: 运营操作
description: 处理不想要的用户与域名
title: 审核操作
description: 针对不受欢迎的用户或域名可以采取的操作。
menu:
docs:
weight: 110
parent: admin
---
## 帐户管理 {#individual-moderation}
## 针对个人用户的审核 {#individual-moderation}
Mastodon运营操作始终作用于本地即从特定服务器查看的内容。一台服务器管理员admin或运营员moderator不能影响另一台服务器上的用户他们只能影响另一台服务器用户的本地服务器副本。
Mastodon 中的审核始终在本站应用,即从特定实例的角度来看。一个实例的管理员或协管员不能影响另一个实例上的用户,他们只能影响该用户在自己实例上的本地副本。
### 禁止登录disable login {#disable-login}
从 v3.5.0 开始,所有默认的用户审核决定都会通过电子邮件通知受影响的用户。用户可以访问申诉页面,在决定做出后的 20 天内提交一次申诉。协管员可以批准或拒绝申诉。
Mastodon可以被禁止登录。这样可以禁止用户对帐户进行任何操作但是其帐户的内容仍保持不变。这个限制是可撤销的任何时候都可以重新激活该用户。本限制仅适用于你服务器的本地用户。
### 标记为敏感内容 {#sensitive-user}
### 隐藏silence {#silence-user}
当一个账户被标记为敏感时,该用户发布的所有媒体内容将自动被[标记为敏感内容](https://docs.joinmastodon.org/user/posting/#cw)。
在Mastodon隐藏silence是沙箱sandbox的同义词。一个被隐藏的帐户不会出现在未关注该帐户的用户面前。该帐户所有内容仍存在这些内容可以通过搜索查找到该帐户可以被提及、被关注但是这些内容是不可见的。
### 冻结 {#freeze-user}
此外,隐藏操作不会影响联邦宇宙。一个本地隐藏了的帐户*不会*自动在其他服务器隐藏
Mastodon 账户可以被冻结。这会阻止用户使用该账户做任何事情,但所有内容仍然完好无损地保留。这种限制是可逆的;账户可以随时解冻。这种限制仅适用于你实例上的本站用户
本限制是可撤销的,任何时间都可以去除该帐户的隐藏。
当用户的账户被冻结时,他们会被重定向到**账户设置**页面,并显示以下信息:
### 封禁suspension {#suspend-user}
> 你不能再登录你的账户,或以任何其他方式使用它,但你的个人资料和其他数据保持完整。
在Mastodon封禁suspension是删除deletion的同义词。该帐户不会出现在搜索之中其用户资料页将消失该帐户的所有嘟文上传关注者以及所有其它数据都将被移除。本限制是**不可逆的**。当一个帐户被解除屏蔽,用户可以重新控制帐户,但旧数据已经一去不复返了
当用户的账户解冻后,正常功能会恢复
## 实例管理 {#server-wide-moderation}
### 限制 {#limit-user}
由于使用帐户管理单独处理来自行为异常服务器的大量用户是让人精疲力竭的事,所以可以预清空来自特定服务器的所有用户,即所谓的**域名屏蔽domain block**。该操作有多个不同严厉程度
之前被称为"隐藏"。被限制的账户将对该实例上的所有其他用户隐藏,除非用户已经关注了被限制的账户。所有内容仍然存在,并且仍然可以通过搜索、提及和关注找到,但内容在公开场合不可见
### 拒绝接收媒体文件reject media {#reject-media}
目前,限制不影响联合功能。在本站被限制的账户在其他实例*不会*被自动限制。账户限制是可逆的。
当这个选项被激活来自该服务器的文件将不会传递至本地。其包括头像、横幅、emoji及媒体附件。
### 封禁 {#suspend-user}
### 隐藏silence {#silence-server}
Mastodon 中的封禁操作意味着账户实际上被删除。该账户不再出现在搜索中,账户页面消失,所有嘟文、上传的内容、关注者和所有其他数据在公开场合被移除。但是,自封禁起 30 天内,所有数据在管理后台仍然保留。这是为了给用户提供与实例管理员合作解决潜在问题并恢复账户的机会。
对来自该服务器的所有帐户应用隐藏silence操作
如果账户在 30 天期限内被恢复,所有数据将再次可被公开访问,不会产生不良影响。 30 天期限过后,用户的**所有**数据将从被实例中清除。管理员还可以选择在 30 天内的任何时候立即删除用户的账户数据
### 屏蔽suspend {#suspend-server}
无论数据在 30 天期限后被删除,还是被管理员提前强制删除,对应账户仍然可以被解除封禁。但是,该账户将不再与之关联的任何数据(状态、个人资料信息、头像或标题图像)。
来自该服务器的所有帐户应用封禁suspension操作。本地将不储存除用户名外的任何数据
于外站账户,封禁将使其取消关注任何本站账户。即使外站账户在 30 天时间窗口内被解除封禁,这些关系也不会恢复
## 反广告措施 {#spam-fighting-measures}
## 对整个站点进行审核 {#server-wide-moderation}
Mastodon有以下基本措施以阻止广告内容
由于单个审核来自行为不端的站点的大量用户可能会很疲惫,因此可以使用**实例屏蔽**的功能对来自特定服务器的所有用户进行预先审核,这有几个不同的严重级别。
* 注册时需确认电子邮件地址
* 基于IP的注册频率限制
### 拒绝媒体 {#reject-media}
然而专业广告发送者spammer将绕过这些措施。你可以应用的措施是**电子邮件域名屏蔽**。在注册期间Mastodon将解析所给电子邮箱地址的A纪录或MX纪录即电子邮件服务器的IP地址并对照动态存储的黑名单中检查该IP地址
启用此选项后,本站不会处理来自该实例的任何文件。这包括头像、背景横幅、表情与媒体附件
### 屏蔽电子邮件域名 {#blocking-by-email-server}
### 限制 {#limit-server}
广告发送者spammer时常使用不同的电子邮件域名以让他们看起来是使用许多不同的电子邮件服务器注册而这些电子邮件域名很难被分别列入黑名单。但是有时这些域名被解析到了同IP地址电子邮件服务器。如果你发现同一时间有大数广告发送者spammer注册你可以使用在线DNS查询工具或 Linux `dig` 组件来检查,例如:`dig example.com` 将查询该域名的所有DNS A纪录。如果你注意到所有域名指向同一IP你可以把它添加至电子邮件域名屏蔽列表中
相当于[限制](#limit-user)来自该实例的所有过去和未来的账户。之前称为"隐藏"
### 封禁IP {#blocking-by-ip}
### 封禁 {#suspend-server}
Mastodon自身不支持基于IP地址的访问者屏蔽这不是一个万无一失的策略。IP有时会被不同的人共享并时常会易手。但可以使用 Linux 防火墙来基于IP地址屏蔽访问者。下面的例子需要使用 `iptables``ipset`
相当于[封禁](#suspend-user)来自该实例的所有过去和未来的账户。除用户名外,不会在本地存储来自该实例的任何内容。
封禁一个实例将删除本站账户与被封禁实例上账户之间的所有现存关注关系。如果外站实例稍后被解除封禁,这些关系不会恢复。
## 反垃圾信息措施 {#spam-fighting-measures}
Mastodon 中有一些基本措施来防止垃圾信息:
* 注册需要确认电子邮件地址
* 按 IP 地址限制注册速率
然而,专业的垃圾信息发送者会绕过这些措施。你可以采用的另一种措施是**电子邮件域名黑名单**。在注册过程中Mastodon 会解析给定电子邮件地址的 A 或 MX 记录,即电子邮件服务器的 IP 地址,并检查该 IP 地址是否在动态存储的黑名单中。
### 按邮箱服务器屏蔽 {#blocking-by-e-mail-server}
垃圾信息发送者经常使用不同的电子邮件域名,使其看起来像是使用了许多不同的邮箱服务器,很难将这些域名全部添加到黑名单。但在某些情况下,所有这些域名都解析到单个邮箱服务器 IP。如果你看到大量垃圾信息发送者同时注册你可以检查这一点使用在线 DNS 查找工具或 Linux 的 `dig` 实用工具,例如 `dig example.com` 将返回该域的所有 DNS A 记录。如果你注意到所有域名的 IP 都相同,你可以将其添加到电子邮件域名黑名单中。
### 按 IP 屏蔽 {#blocking-by-ip}
在 Mastodon 本身中无法按 IP 地址屏蔽访问者,而且这不是一种万无一失的策略。 IP 有时由很多不同的人共享,且有时会更换。然而,可以在 Linux 中使用防火墙按 IP 地址屏蔽访问者。以下是使用 `iptables``ipset` 的示例:
```bash
# Install ipset
# 安装 ipset
sudo apt install ipset
# Create blacklist named "spambots"
# 创建名为 "spambots" 的黑名单
sudo ipset create spambots nethash
# Add 1.2.3.4 to the blacklist
# 将 1.2.3.4 添加到黑名单
sudo ipset add spambots 1.2.3.4
# Add firewall rule based on the blacklist
# 基于黑名单添加防火墙规则
sudo iptables -I INPUT 1 -m set --match-set spambots src -j DROP
```
但是注意,不要把你自己封禁了。
小心不要将自己锁在机器之外
{{< translation-status-zh-cn raw_title="Moderation actions" raw_link="/admin/moderation/" last_tranlation_time="2020-05-08" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
### 用于审核级别事件的网络钩子 {#report-events-webhook}
你可以创建网络钩子通过实时通知应用程序系统事件来促进审核API的自动化。这也实现了与 Discord、 IRC 和 Slack 等聊天应用的集成,有助于协调审核工作。
作为可选操作,你可使用来自 WebSub 规范的 X-Hub-Signature 标头来验证载荷的真实性。
当前支持的事件:
* account.approved
* account.created
* account.updated
* report.created
* report.updated
* status.created
* status.updated
#### 示例载荷:
```json
{
"event":"report.created",
"created_at":"2023-10-26T13:34:00.351Z",
"object":{
"id":"8437",
"action_taken":false,
"action_taken_at":null,
"category":"violation",
"comment":"",
"forwarded":true,
"created_at":"2023-10-26T13:34:00.348Z",
"updated_at":"2023-10-26T13:34:00.348Z",
"account":{
"id":"123456789",
"username":"bobisaburger",
"domain":null,
"created_at":"2023-07-13T04:39:22.493Z",
"email":"bobisaburger@emailservice.com",
"ip":"12.34.56.78",
"confirmed":true,
"suspended":false,
"silenced":false,
"sensitized":false,
"disabled":false,
"approved":true,
"locale":"en",
"invite_request":"I would love to be a member of your instance!",
"ips":[
{
"ip":"12.34.56.78",
"used_at":"2023-07-13T04:45:31.835Z"
},
{
"ip":"98.76.54.32",
"used_at":"2023-07-13T04:39:22.722Z"
}
],
"account":{
"id":"123456789",
"username":"bobisaburger",
"acct":"bobisaburger",
"display_name":"bobisaburger",
"locked":false,
"bot":false,
"discoverable":null,
"group":false,
"created_at":"2023-07-13T00:00:00.000Z",
"note":"",
"url":"https://mastodonwebsite/@bobisaburger",
"uri":"https://mastodonwebsite/users/bobisaburger",
"avatar":"https://locationofavatar.com/image.jpg",
"avatar_static":"https://locationofavatar.com/image.jpg",
"header":"locationofheader.com/image.jpg",
"header_static":"locationofheader.com/image.jpg",
"followers_count":100,
"following_count":200,
"statuses_count":9,
"last_status_at":"2023-08-05",
"noindex":true,
"emojis":[
],
"roles":[
],
"fields":[
]
},
"role":{
"id":"-99",
"name":"",
"permissions":"65536",
"color":"",
"highlighted":false
}
},
"target_account":{
"id":"123454321",
"username":"cheeseperson",
"domain":"someothermastodonsite.com",
"created_at":"2023-08-20T00:00:00.000Z",
"email":null,
"ip":null,
"confirmed":null,
"suspended":false,
"silenced":false,
"sensitized":false,
"disabled":null,
"approved":null,
"locale":null,
"invite_request":null,
"ips":null,
"account":{
"id":"123454321",
"username":"cheeseperson",
"acct":"cheeseperson@someothermastodonsite.com",
"display_name":"cheeseperson",
"locked":false,
"bot":false,
"discoverable":false,
"group":false,
"created_at":"2023-08-20T00:00:00.000Z",
"note":"",
"url":"https://someothermastodonsite.com/@cheeseperson",
"uri":"https://someothermastodonsite.com/users/cheeseperson",
"avatar":"https://someothermastadonsite.com/avatars/original/missing.png",
"avatar_static":"https://someothermastadonsite.com/avatars/original/missing.png",
"header":"locationofheader.com/image.jpg",
"header_static":"locationofheader.com/image.jpg",
"followers_count":2,
"following_count":2,
"statuses_count":95,
"last_status_at":"2023-10-26",
"emojis":[
],
"fields":[
]
},
"role":null
},
"assigned_account":null,
"action_taken_by_account":null,
"statuses":[
{
"id":"12345678987654321",
"created_at":"2023-10-26T11:29:13.000Z",
"in_reply_to_id":"1918282746465",
"in_reply_to_account_id":"101010101010",
"sensitive":false,
"spoiler_text":"",
"visibility":"public",
"language":"de",
"uri":"https://someothermastodonsite.com/users/cheeseperson/statuses/111301083360371621",
"url":"https://someothermastodonsite.com/@cheeseperson/111301083360371621",
"replies_count":0,
"reblogs_count":0,
"favourites_count":0,
"edited_at":"2023-10-26T11:30:31.000Z",
"content":"<p>Here is some content</p>",
"reblog":null,
"account":{
"id":"123454321",
"username":"cheeseperson",
"acct":"cheeseperson@someothermastodonsite.com",
"display_name":"cheeseperson",
"locked":false,
"bot":false,
"discoverable":false,
"group":false,
"created_at":"2023-08-20T00:00:00.000Z",
"note":"",
"url":"https://someothermastodonsite.com/@cheeseperson",
"uri":"https://someothermastodonsite.com/users/cheeseperson",
"avatar":"https://someothermastadonsite.com/avatars/original/missing.png",
"avatar_static":"https://someothermastadonsite.com/avatars/original/missing.png",
"header":"locationofheader.com/image.jpg",
"header_static":"locationofheader.com/image.jpg",
"followers_count":2,
"following_count":2,
"statuses_count":95,
"last_status_at":"2023-10-26",
"emojis":[
],
"fields":[
]
},
"media_attachments":[
],
"mentions":[
{
"id":"101010101010",
"username":"thirdperson",
"url":"https://thirdpersonsinstance.com/@thirdperson",
"acct":"thirdperson@emailwebsite.com"
}
],
"tags":[
],
"emojis":[
],
"card":null,
"poll":null
}
],
"rules":[
{
"id":"2",
"text":"不要做一个招人讨厌的人!"
}
]
}
}
```
{{< translation-status-zh-cn raw_title="Moderation actions" raw_link="/admin/moderation/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,5 +1,5 @@
---
title: 安装可选特色功能
title: 安装可选功能
menu:
docs:
weight: 40
@ -7,4 +7,10 @@ menu:
identifier: admin-optional
---
{{< translation-status-zh-cn raw_title="Installing optional features" raw_link="/admin/optional/" last_tranlation_time="2020-05-04" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
Mastodon提供了一些可以根据需要使用的可选功能。
- [对象存储](./object-storage/)
- [匿名服务](./tor/)
- [单点登录](./sso/)
{{< translation-status-zh-cn raw_title="Installing optional features" raw_link="/admin/optional/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -0,0 +1,34 @@
---
title: 验证码
description: 缓解自动注册机器人的问题
menu:
docs:
weight: 30
parent: admin-optional
---
从 4.2 版本开始, Mastodon 支持使用验证码技术来帮助缓解机器人注册新账户的问题。
启用验证码后,新注册用户将需要在电子邮件验证过程中完成一个质询响应。
![](/assets/captcha/user-view.png)
{{< hint style="danger" >}}
对于某些人来说,使用中心化的验证码服务可能会引起安全和隐私方面的担忧。
此外,验证码可能会使注册过程的可访问性大大降低,尤其是对于视力障碍人士,如盲人或视力低下的人而言。
{{</ hint >}}
目前, hCaptcha 是 Mastodon 唯一支持的验证码提供商。
未来可能会添加其他提供商。
## hCaptcha
- 在 [hcaptcha.com](https://www.hcaptcha.com) 创建一个免费的 hCaptcha 账户
- 完成注册后,使用 hCaptcha 仪表板添加新站点,输入你的 Mastodon 站点域名并获取站点密钥(Site Key)
- 从 hCaptcha 的账户设置菜单中获取你的密钥(Secret Key)
- 将这些值添加到你的 Mastodon 环境配置中,分别添加 `HCAPTCHA_SITE_KEY``HCAPTCHA_SECRET_KEY`
- 重启服务器上运行的 Mastodon 服务
- 从 Mastodon 网页界面导航至**管理**>**服务器设置**>**注册**,并勾选标有"要求新用户解决验证码以确认其账户"的选项
![](/assets/captcha/admin-view.png)
{{< translation-status-zh-cn raw_title="Captcha" raw_link="/admin/optional/captcha/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,164 +0,0 @@
---
title: 全文搜索
description: 设置Elasticsearch来搜索自己发出的嘟文、自己喜欢的嘟文、自己的书签和自己被提及的嘟文。
menu:
docs:
weight: 10
parent: admin-optional
---
当有可用Elasticsearch时Mastodon支持全文搜索。Mastodon的全文搜索允许登录用户从他们自己的嘟文、他们喜欢的嘟文、他们的书签和他们被提及的嘟文中查找相应结果。Mastodon有意禁用了在全数据库搜索任意关键词的功能。
## 安装 Elasticsearch {#install}
Elasticsearch 需要 Java runtime。如果你还没有安装 Java请立刻安装上它。以下操均假定你已经登录为`root`用户:
```bash
apt install openjdk-8-jre-headless
```
添加Elasticsearch官方软件仓库至apt
```bash
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add -
echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | tee -a /etc/apt/sources.list.d/elastic-6.x.list
apt update
```
现在,你可以安装 Elasticsearch
```bash
apt install elasticsearch
```
{{< hint style="warning" >}}
**安全警告:** 默认情况下Elasticsearch仅绑定于localhost即无法从外部网络访问。你可以通过查看 `/etc/elasticsearch/elasticsearch.yml` 中的 `network.host` 来检查 Elasticsearch 绑定了哪些地址。考虑到由于缺乏认证层,任何能访问 Elasticsearch 的人都可以读取或修改里面的数据。因此,确保访问安全非常重要。如[主要安装说明](../../prerequisites/#install-a-firewall-and-only-whitelist-ssh-http-and-https-ports)中所述防火墙建议仅暴露了22、80、443端口。如果你是一个多主机配置你必须知道如何保证内部流量安全。
{{< /hint >}}
{{< hint style="danger" >}}
**安全警告:** 由于近期Elasticsearch所使用的`log4j`库被披露出[安全漏洞](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-44228),使用了旧版本`log4j`(`2.0``2.14.1`)的ES可能会受到影响。如果使用了这些版本的`log4j`,请参阅 [此 issue](https://github.com/elastic/elasticsearch/issues/81618#issuecomment-991000240) 来暂时缓解此问题。
{{< /hint >}}
启动 Elasticsearch
```bash
systemctl enable elasticsearch
systemctl start elasticsearch
```
## 配置 Mastodon {#config}
编辑 `.env.production`,添加如下变量:
```bash
ES_ENABLED=true
ES_HOST=localhost
ES_PORT=9200
```
如果你同一台机器上运行多个Mastodon服务器你计划让它们使用同一个Elasticsearch请确保他们都配置了互不重复的 `REDIS_NAMESPACE` 以分别他们的索引。如果你需要覆盖Elasticsearch索引前缀你可以直接设置 `ES_PREFIX`
保存新设置之后使用如下命令创建Elasticsearch索引
```bash
RAILS_ENV=production bundle exec rake chewy:upgrade
```
重启Mastodon进程以使新配置生效
```bash
systemctl restart mastodon-sidekiq
systemctl reload mastodon-web
```
现在新的嘟文将会被写入Elasticsearch索引。最后一步是导入所有旧有数据。这将花费很长一段时间
```bash
RAILS_ENV=production bundle exec rake chewy:sync
```
{{< hint style="warning" >}}
**兼容性提示:** Ruby 2.6.0 由于已知Bug无法进行上述操作。其它Ruby版本例如2.6.1,并不存在这个问题。
{{< /hint >}}
## 其它语言的搜索优化
### 中文搜索优化 {#chinese-search-optimize}
Elasticsearch默认使用标准分析器这对于中文来说可能并不太适合。为了提高搜索体验你可以安装特定语言的专用分析器。在创建Elasticsearch索引之前执行
安装 [elasticsearch-analysis-ik](https://github.com/medcl/elasticsearch-analysis-ik)、[elasticsearch-analysis-stconvert](https://github.com/medcl/elasticsearch-analysis-stconvert) 插件至 Elasticsearch。
并对源码做出如下修改:
```diff
diff --git a/app/chewy/accounts_index.rb b/app/chewy/accounts_index.rb
--- a/app/chewy/accounts_index.rb
+++ b/app/chewy/accounts_index.rb
@@ -4,7 +4,7 @@ class AccountsIndex < Chewy::Index
settings index: { refresh_interval: '5m' }, analysis: {
analyzer: {
content: {
- tokenizer: 'whitespace',
+ tokenizer: 'ik_max_word',
filter: %w(lowercase asciifolding cjk_width),
},
diff --git a/app/chewy/statuses_index.rb b/app/chewy/statuses_index.rb
--- a/app/chewy/statuses_index.rb
+++ b/app/chewy/statuses_index.rb
@@ -16,9 +16,17 @@ class StatusesIndex < Chewy::Index
language: 'possessive_english',
},
},
+ char_filter: {
+ tsconvert: {
+ type: 'stconvert',
+ keep_both: false,
+ delimiter: '#',
+ convert_type: 't2s',
+ },
+ },
analyzer: {
content: {
- tokenizer: 'uax_url_email',
+ tokenizer: 'ik_max_word',
filter: %w(
english_possessive_stemmer
lowercase
@@ -27,6 +35,7 @@ class StatusesIndex < Chewy::Index
english_stop
english_stemmer
),
+ char_filter: %w(tsconvert),
},
},
}
diff --git a/app/chewy/tags_index.rb b/app/chewy/tags_index.rb
--- a/app/chewy/tags_index.rb
+++ b/app/chewy/tags_index.rb
@@ -2,10 +2,19 @@
class TagsIndex < Chewy::Index
settings index: { refresh_interval: '15m' }, analysis: {
+ char_filter: {
+ tsconvert: {
+ type: 'stconvert',
+ keep_both: false,
+ delimiter: '#',
+ convert_type: 't2s',
+ },
+ },
analyzer: {
content: {
- tokenizer: 'keyword',
+ tokenizer: 'ik_max_word',
filter: %w(lowercase asciifolding cjk_width),
+ char_filter: %w(tsconvert),
},
edge_ngram: {
```
{{< translation-status-zh-cn raw_title="Full-text search" raw_link="/admin/optional/elasticsearch/" last_tranlation_time="2020-05-05" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}

View file

@ -0,0 +1,129 @@
---
title: 通过 nginx 代理对象存储
description: 从自己的域名提供 Mastodon 中用户上传的文件
---
当使用 Amazon S3、Wasabi、Google Cloud 或其他对象存储提供商作为 Mastodon 的对象存储时,默认情况下,文件及其 URL 会通过存储提供商本身提供。这有以下缺点:
- 带宽通常是按量计费且非常昂贵
- 如果你决定稍后更换提供商URL 将会失效
你可以选择从自己的域名提供文件,并在此过程中加入缓存机制。在 Mastodon 中,访问模式显示新文件经常被多个客户端同时访问,因为它们出现在通过流式 API 提供的新贴文中或通过联邦与州共享;相比之下,旧内容的访问频率较低。因此,仅依靠缓存并不能显著减少代理到实际对象存储的带宽使用。为了解决这个问题,我们可以实现一个缓存锁定机制,确保一次只进行一个代理请求。
以下是实现这一目标的nginx配置示例
```nginx
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name files.example.com;
root /var/www/html;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
keepalive_timeout 30;
location = / {
index index.html;
}
location / {
try_files $uri @s3;
}
set $s3_backend 'https://YOUR_BUCKET_NAME.YOUR_S3_HOSTNAME';
location @s3 {
limit_except GET {
deny all;
}
resolver 8.8.8.8;
proxy_set_header Host YOUR_BUCKET_NAME.YOUR_S3_HOSTNAME;
proxy_set_header Connection '';
proxy_set_header Authorization '';
proxy_hide_header Set-Cookie;
proxy_hide_header 'Access-Control-Allow-Origin';
proxy_hide_header 'Access-Control-Allow-Methods';
proxy_hide_header 'Access-Control-Allow-Headers';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header x-amz-bucket-region;
proxy_hide_header x-amzn-requestid;
proxy_ignore_headers Set-Cookie;
proxy_pass $s3_backend$uri;
proxy_intercept_errors off;
proxy_cache CACHE;
proxy_cache_valid 200 48h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_lock on;
expires 1y;
add_header Cache-Control public;
add_header 'Access-Control-Allow-Origin' '*';
add_header X-Cache-Status $upstream_cache_status;
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src 'none'; form-action 'none'";
}
}
```
{{< hint style="info" >}}
我们使用 `$s3_backend` 作为变量来强制 nginx 对其值执行 DNS 解析,因为对象存储提供商的 IP 地址可能不会始终保持不变。
{{</ hint >}}
上述配置实现了以下效果:
- 阻止针对对象存储提供商的除 GET 请求之外的请求
- 阻止任何经过身份验证的请求到达对象存储提供商
- 阻止对象存储提供商设置cookie
- 移除对象存储提供商返回的不必要的标头信息
- 缓存有效文件最多 48 小时
- 如果对象存储不可用,允许使用旧缓存
- 使用缓存锁防止同时向对象存储发出请求
- 使返回的所有文件可被浏览器缓存长达一年
- 添加 Mastodon 网页界面所需的 CORS 头信息
- 添加一个特殊的头信息,告诉用户请求是否命中缓存
确保替换以下内容:
- `files.example.com`
- `YOUR_BUCKET_NAME`
- `YOUR_S3_HOSTNAME`
使用你的实际值,将配置保存到 `/etc/nginx/sites-available/files.example.com`,然后通过以下命令启用它:
```bash
ln -s /etc/nginx/sites-available/files.example.com /etc/nginx/sites-enabled/
systemctl reload nginx
```
你还需要为其获取SSL证书
```bash
certbot --nginx -d files.example.com
systemctl reload nginx
```
最后,你需要确保 Mastodon 使用你的新代理生成文件 URL。编辑 Mastodon 的 `.env.production` 添加:
```bash
S3_ALIAS_HOST=files.example.com
```
然后重启 Mastodon
```bash
systemctl restart mastodon-sidekiq
systemctl reload mastodon-web
```
{{< hint style="success" >}}
**现在你可以在浏览器中访问你的 Mastodon 以确认一切正常加载**
{{< /hint >}}
{{< translation-status-zh-cn raw_title="Proxying object storage through nginx" raw_link="/admin/optional/object-storage-proxy/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -0,0 +1,320 @@
---
title: 对象存储
description: 使用外部对象存储来存储 Mastodon 中用户上传的文件
menu:
docs:
weight: 15
parent: admin-optional
---
用户上传的文件可以存储在主服务器的文件系统中,或者使用外部对象存储服务器。使用外部对象存储对于扩展 Mastodon 实例来说可能是必需的。
## 使用文件系统 {#FS}
最简单的存储用户上传文件的方式是使用服务器的文件系统。这是默认的工作方式,适用于小型服务器。
默认情况下, Mastodon 会将文件上传存储在安装目录下的 `public/system` 文件夹中,但可以通过使用 `PAPERCLIP_ROOT_PATH` 环境变量来覆盖此设置。
默认情况下,这些文件可以通过 `https://your-domain/system` 访问,可以使用 `PAPERCLIP_ROOT_URL``CDN_HOST` 来覆盖此访问路径。
{{< hint style="info" >}}
虽然使用服务器的文件系统对小型服务器来说完全可用,但使用外部对象存储更具可扩展性。
{{</ hint >}}
{{< hint style="danger" >}}
必须配置 Web 服务器,使其能够提供这些文件,但不允许列出它们(也就是说 `https://your-domain/system/` 不应返回文件列表)。如果你使用与 Mastodon 一起分发的配置文件,情况应该就是这样,但最好再次检查一下。
{{</ hint >}}
## 兼容 S3 的对象存储后端 {#S3}
Mastodon 可以使用兼容 S3 的对象存储后端。 建议支持 ACL因为 ACL 允许 Mastodon 快速地让被封禁用户的媒体附件不可用,或略微提高私有数据的安全性。
Mastodon 使用 S3 API (`S3_REGION`, `S3_ENDPOINT`, `S3_BUCKET`,
`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `S3_SIGNATURE_VERSION`,
`S3_OVERRIDE_PATH_STYLE`) 进行所有的写入、删除和权限修改操作。这包括媒体上传(来自 Web 界面、 Mastodon API 客户端和 ActivityPub 服务器)、媒体删除(贴文被编辑或删除时)以及阻止对媒体的访问(当帐户被暂停时)。
Mastodon 会向 Web 界面、Mastodon API 客户端和 ActivityPub 服务器发送 URL用于所有“读取”操作。因此这些操作是匿名的不需要身份验证或授权并使用纯 HTTP GET 方法,这意味着它们可以通过反向代理和 CDN 路由并被缓存。 这也意味着这些 URL 可以包含与 S3 存储提供商本身使用的主机/域名完全不同的主机/域名(根据需要)。 请查看下面的详细文档,其中描述了如何构造这些 URL 以及涉及哪些环境变量。
要启用 S3 存储,请将 `S3_ENABLED` 环境变量设置为 `true`
### 用于 S3 API 访问的环境变量
- `S3_REGION` (默认为 'us-east-1',如果使用 AWS S3 则必需提供,使用其他存储提供商可能不需要)
- `S3_ENDPOINT` (默认为 'https://s3.<S3_REGION>.amazonaws.com' 如果不使用 AWS S3 则必需提供)
- `S3_BUCKET=mastodata` (将 `mastodata` 替换为你的存储桶名称)
- `AWS_ACCESS_KEY_ID``AWS_SECRET_ACCESS_KEY` 需要设置为你的凭据
- `S3_SIGNATURE_VERSION` (默认为 'v4',应该与大多数存储提供商兼容)
- `S3_OVERRIDE_PATH_STYLE` (仅当配置了 `S3_ENDPOINT` 时使用, 如果存储提供商要求将 API 操作发送到 '<S3_BUCKET>.<S3_ENDPOINT>`(域名样式),请将其设置为 `true`)
### 用于客户端访问媒体对象的环境变量
- `S3_PROTOCOL` (默认为 `https`)
- `S3_HOSTNAME` (默认为 's3-<S3_REGION>.amazonaws.com' 如果不使用 AWS S3 且未设置 `S3_ALIAS_HOST`,则为必需)
- `S3_ALIAS_HOST` (如果你不希望 `S3_BUCKET` 包含在媒体 URL 中,可以使用 `S3_ALIAS_HOST` 代替 `S3_HOSTNAME` 这需要你在存储提供商前面配置一个反向代理或 CDN)
如上所述当客户端需要从存储提供商访问媒体对象时Mastodon 将向客户端发送 URL。 这些 URL 构造如下:
- 如果未设置 `S3_ALIAS_HOST`,则 URL 将为 '<S3_PROTOCOL>://<S3_HOSTNAME>/<S3_BUCKET>/\<对象路径\>'
- 如果设置了 `S3_ALIAS_HOST`,则 URL 将为 '<S3_PROTOCOL>://<S3_ALIAS_HOST>/\<对象路径\>'
注意,当设置了 `S3_ALIAS_HOST` 时,存储桶名称 **不** 包含在生成的 URL 中; 这意味着存储桶名称必须包含在 `S3_ALIAS_HOST` 中(称为“域名样式”对象访问),或者 `S3_ALIAS_HOST` 必须指向一个反向代理或 CDN它可以将存储桶名称包含在用于将请求发送到存储提供商的 URL 中。 这种类型的配置允许你从实例的客户端“隐藏”存储提供商,这意味着你可以更改存储提供商,而无需更改生成的 URL。
除隐藏存储提供商之外,这还可以让你在从存储提供商拉取媒体后缓存媒体,从而降低存储提供商的出口带宽成本。 这可以在你自己的反向代理中完成,也可以通过使用 CDN 来完成。
{{< page-ref page="admin/optional/object-storage-proxy.md" >}}
{{< hint style="info" >}}
你必须使用 CORS 标头来提供文件,否则 Mastodon Web UI 的某些功能将无法正常工作。 例如,`Access-Control-Allow-Origin: *`
{{</ hint >}}
### 可选环境变量
#### `S3_OPEN_TIMEOUT`
默认值5 (秒)
HTTP 处理程序在尝试打开新的 HTTP 会话时应超时的秒数。
#### `S3_READ_TIMEOUT`
默认值5 (秒)
HTTP 处理程序在等待 HTTP 响应时应超时的秒数。
#### `S3_FORCE_SINGLE_REQUEST`
默认值false
如果你在处理大型文件时遇到问题,请将其设置为 `true`
#### `S3_ENABLE_CHECKSUM_MODE`
默认值false
使在 Mastodon 从存储提供商检索对象时验证对象校验和。 此功能在 AWS S3 中可用,但在其他兼容 S3 的实现中可能不可用。
#### `S3_STORAGE_CLASS`
默认值none
当使用 AWS S3 时,此变量可以设置为 [存储类](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html) 的其中一个选项,这些选项会影响所选的用于上传对象的存储(以及它们的访问时间和成本)。 如果未指定存储类,则 AWS S3 将使用 `STANDARD` 类,但选项包括 `REDUCED_REDUNDANCY``GLACIER` 等。
#### `S3_MULTIPART_THRESHOLD`
默认值15 (兆字节)
此大小及以下的对象将以单个操作上传,但更大的对象将使用多部分分块机制上传,这可以提高传输速度和可靠性。
#### `S3_PERMISSION`
默认值:`public-read`
定义上传新文件时的 S3 对象 ACL。 使用 [S3 阻止公共访问](https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html) 并启用 `BlockPublicAcls` 选项时请谨慎,因为使用 ACL `public-read` 上传对象将失败 (403)。 在这种情况下,需将 `S3_PERMISSION` 设置为 `private`
{{< hint style="danger" >}}
无论 ACL 配置如何,你的 S3 存储桶都必须设置为确保所有对象都是公共可读,但不可写或可列出。 同时Mastodon 本身应该对存储桶具有写入权限。 此配置通常在所有 S3 提供商中保持一致,常用提供商在本指南后面会重点介绍。
{{</ hint >}}
#### `S3_BATCH_DELETE_LIMIT`
默认值: `1000`
官方的 [Amazon S3 API](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html) 可以处理在一个批处理作业中删除 1,000 个对象,但一些提供商可能在处理一个请求中的这么多对象时遇到问题,或者提供更低的限制。
#### `S3_BATCH_DELETE_RETRY`
默认值: 3
在批处理删除操作期间S3 提供商可能会在处理删除请求时周期性地失败或超时。 Mastodon 会退避并重试该请求,直到达到最大重试次数。
### MinIO
MinIO 是 S3 对象提供程序的开源实现。 本节不介绍如何安装它,而是介绍如何配置存储桶以在 Mastodon 中使用。
你需要为匿名访问设置一个策略,该策略允许对存储桶包含的对象进行只读访问,而不允许列出它们。
为此,你需要设置一个自定义策略(将 `mastodata` 替换为你的 S3 存储桶的实际名称):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mastodata/*"
]
}
]
}
```
Mastodon 本身需要能够写入存储桶,因此请使用你的 MinIO 管理员帐户(不建议)或附加以下策略的 Mastodon 专用帐户(建议)(将 `mastodata` 替换为你的 S3 存储桶的实际名称):
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::mastodata/*"
}
]
}
```
你可以通过 MinIO 控制台(基于 Web 的用户界面)或命令行客户端 (`mcli` / `mc`) 设置这些策略。
#### 使用 MinIO 控制台
连接到 MinIO 控制台 Web 界面并创建一个新存储桶(或导航到你现有的存储桶):
![](/assets/object-storage/minio-bucket.png)
然后,将“访问策略”配置为允许读取访问 (`s3:GetObject`) 而未写入访问或列出对象的能力的自定义策略(见上文):
![](/assets/object-storage/minio-access-policy.png)
{{< hint style="info" >}}
如果 MinIO 控制台不允许你设置“自定义”策略,则可能需要更新 MinIO。 如果你在 *独立**文件系统* 模式下使用 MinIO则 [`RELEASE.2022-10-24T18-35-07Z`](https://github.com/minio/minio/releases/tag/RELEASE.2022-10-24T18-35-07Z) 应该是一个安全的更新版本,不需要 [涉及迁移过程](https://min.io/docs/minio/linux/operations/install-deploy-manage/migrate-fs-gateway.html#migrate-from-gateway-or-filesystem-mode)。
{{< /hint >}}
新建一个 `mastodon-readwrite` 策略(见上文):
![](/assets/object-storage/minio-mastodon-readwrite.png)
最后,使用 `mastodon-readwrite` 策略创建一个新的 `mastodon` 用户:
![](/assets/object-storage/minio-mastodon-user.png)
#### 使用命令行实用程序
使用 [MinIO 客户端](https://min.io/docs/minio/linux/reference/minio-mc.html) 命令行实用程序(可以根据安装位置调用 `mc``mcli`)也可以实现相同的目的。
创建一个新存储桶:
`mc mb myminio/mastodata`
将上面的匿名访问策略保存为 `anonymous-readonly-policy.json`,并将 Mastodon 用户访问策略保存为 `mastodon-readwrite.json`(确保将 `mastodata` 替换为你新创建的存储桶的名称)。
设置存储桶的匿名访问策略:
`mc anonymous set-json anonymous-readonly-policy.json myminio/mastodata`
添加 `mastodon-readwrite` 策略:
`mc admin policy add myminio mastodon-readwrite mastodon-readwrite.json`
添加 `mastodon` 用户(替换密码):
`mc admin user add myminio mastodon SECRET_PASSWORD`
`mastodon-readwrite` 策略应用到 `mastodon` 用户:
`mc admin policy set myminio mastodon-readwrite user=mastodon`
### Wasabi 对象存储
创建一个新存储桶并定义其策略,允许对象进行匿名读取但不可列出:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mastodata/*"
}
]
}
```
![](/assets/object-storage/wasabi-access-policy.png)
{{< hint style="info" >}}
如果你使用旧存储桶,请确保你没有通过 Wasabi 的旧版访问控制设置授予“所有人”读取对象的权限,因为该设置允许列出对象并优先于上面定义的 IAM 策略。
![](/assets/object-storage/wasabi-access-control.png)
{{< /hint >}}
然后,创建一个 `mastodon-readwrite` 策略以授予对你的存储桶的读写访问权限:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::mastodata/*"
}
]
}
```
![](/assets/object-storage/wasabi-mastodon-readwrite.png)
最后,创建一个新的 `mastodon` 用户,并且不要忘记启用 `mastodon-readwrite` 策略:
![](/assets/object-storage/wasabi-mastodon-user.png)
在 Mastodon 端,你需要设置`S3_FORCE_SINGLE_REQUEST=true`来正确处理大型上传。
### DigitalOcean Spaces
在你的 DigitalOcean Spaces 存储桶中,确保“文件列表”对于拥有访问密钥的用户是“受限制的”。
![](/assets/object-storage/do-spaces.png)
### Scaleway
如果你想使用 Scaleway 对象存储,我们强烈建议你创建一个专用于 Mastodon 实例资产的 Scaleway 项目,并使用自定义 IAM 策略。
首先,创建一个新的 Scaleway 项目,在其中创建对象存储桶。 你需要将存储桶的可见性设置为“私有”,以不允许列出对象。
![](/assets/object-storage/scaleway-bucket.png)
现在你的存储桶已创建,你需要创建 API 密钥,以便在你的 Mastodon 实例配置中使用。
前往 IAM 设置(在你的组织菜单中,屏幕的右上角),然后创建一个新的 IAM 策略(例如 `mastodon-media-access`
![](/assets/object-storage/scaleway-policy.jpg)
此策略需要有一个规则,允许它在你上面创建的 Scaleway 项目(作用域)中读取、写入和删除对象。
![](/assets/object-storage/scaleway-policy-rules.jpg)
然后前往 IAM 应用程序页面,创建一个新的应用程序(例如 `my-mastodon-instance`),并选择你上面创建的策略。
最后单击你创建的应用程序然后单击“API 密钥”,并创建一个新的 API 密钥,以便在你的实例配置中使用。 你应该使用“是,设置首选项目”选项,并选择你上面创建的项目作为此密钥的默认项目。
![](/assets/object-storage/scaleway-api-key.png)
复制 Access Key ID 和 Secret并将它们用于你的 `AWS_ACCESS_KEY_ID``AWS_SECRET_ACCESS_KEY` 这两个 Mastodon 配置变量。
### Exoscale
在 Exoscale 中,你的存储桶不应有任何读取 ACLMastodon 将根据需要在对象本身上设置 ACL
你需要为 Mastodon 应用程序创建一个 API 密钥,该密钥限于对象存储 (`sos`) 服务,限于你的存储桶,并且操作不受限制。
![](/assets/object-storage/exoscale.png)
在 Mastodon 端,你需要设置`S3_FORCE_SINGLE_REQUEST=true`才能正确处理大型上传。
### Cloudflare R2
Cloudflare R2 不支持 ACL因此需要指示 Mastodon 不尝试设置他们。 为此,需要将 `S3_PERMISSION` 环境变量设置为空字符串。
{{< hint style="warning" >}}
如果不支持 ACL被封禁的用户的媒体文件仍然可以访问。
{{< /hint >}}
要获取在 Mastodon 中使用的凭据,请选择“管理 R2 API 令牌”并创建一个新的 API 令牌,具有“编辑”权限。
{{< hint style="warning" >}}
本节正在建设中。
{{< /hint >}}
{{< translation-status-zh-cn raw_title="Object storage" raw_link="/admin/optional/object-storage/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,13 +1,15 @@
---
title: 单点登录SSO
title: 单点登录
menu:
docs:
weight: 30
weight: 40
parent: admin-optional
---
{{< hint style="danger" >}}
本页面仍在建设中。
此页面正在建设中。
目前,请参考[这个拉取请求](https://github.com/mastodon/mastodon/pull/16221)
{{< /hint >}}
{{< translation-status-zh-cn raw_title="Single Sign On" raw_link="/admin/optional/sso/" last_tranlation_time="2020-05-04" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
{{< translation-status-zh-cn raw_title="Single Sign On" raw_link="/admin/optional/sso/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,31 +1,31 @@
---
title: 匿名服务
description: 通过Tor的匿名服务来访问Mastodon
title: 洋葱服务
description: 通过 Tor 洋葱服务提供 Mastodon 服务
menu:
docs:
weight: 20
parent: admin-optional
---
可以通过Tor的匿名服务来访问Mastodon。这将给你一个只能通过 Tor 网络连接的 \*.onion 地址
Mastodon 可以通过 Tor 作为洋葱服务提供服务。这将为你提供一个 `*.onion` 地址,该地址只能在连接到 Tor 网络时使用
## 安装 Tor {#install}
首先Tor的Debian软件仓库需要被添加至apt中。
首先需要将 Tor 的 Debian 存储库添加到 apt 中。
```text
deb https://deb.torproject.org/torproject.org stretch main
deb-src https://deb.torproject.org/torproject.org stretch main
```
接下来添加相应gpg密钥。
接下来添加 gpg 密钥。
```bash
curl https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --import
gpg --export A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89 | apt-key add -
```
最后安装所需软件包。
最后安装所需软件包。
```bash
apt install tor deb.torproject.org-keyring
@ -33,10 +33,10 @@ apt install tor deb.torproject.org-keyring
## 配置 Tor {#configure}
编辑 `/etc/tor/torrc` 并添加如下设置。
编辑 `/etc/tor/torrc` 文件并添加以下配置。
```text
HiddenServiceDir /var/lib/tor/hidden_service/
HiddenServiceDir /var/lib/tor/onion_service/
HiddenServiceVersion 3
HiddenServicePort 80 127.0.0.1:80
```
@ -47,34 +47,37 @@ HiddenServicePort 80 127.0.0.1:80
sudo service tor restart
```
现在你的Tor域名可以在 `/var/lib/tor/hidden_service/hostname` 找到。
现在可以在 `/var/lib/tor/hidden_service/hostname` 找到你的 Tor 主机名
## 移动你的Mastodon配置 {#nginx}
## 移动你的 Mastodon 配置 {#nginx}
我们将需要将你的Mastodon配置告诉Nginx两次。为了不自我重复[DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)我们需要将Mastodon配置移动到一个可被引用的独立文件
我们需要在 Nginx 中配置两次 Mastodon。为了保持["DRY"](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)原则,我们需要将 Mastodon 配置移到自己的文件中,以便之后可以引用
`/etc/nginx/snippets/mastodon.conf` 创建一个新文件。放入除`listen``server_name``include`及所有SSL相关选项之外的所有配置参数至新文件中。你的新文件看起来可能像这样。
创建一个新文件 `/etc/nginx/snippets/mastodon.conf`。复制所有 Mastodon 配置参数,除了 `listen``server_name``include` 指令以及所有 SSL 选项。包含一个 `Onion-Location` 头,让支持的浏览器知道该服务也可以通过 Tor 访问。你的新文件应该看起来像这样:
```text
```nginx
add_header Referrer-Policy "same-origin";
add_header Onion-Location mastodon.qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7.onion$request_uri;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
root /home/mastodon/live/public;
# …
error_page 500 501 502 503 504 /500.html;
access_log /var/log/nginx/mastodon_access.log;
error_log /var/log/nginx/mastodon_error.log warn;
```
替换你的旧Mastodon配置文件在新配置文件中添加一个include指令。
在新的配置文件中,在原来 Mastodon 配置的位置添加 `include` 指令。
你的Nginx配置文件将看起来像这样。
你的 Nginx 配置文件现在应该看起来像这样:
```text
```nginx
server {
listen 80;
server_name mastodon.example.com;
@ -97,13 +100,15 @@ server {
}
```
## 通过http提供Tor服务 {#http}
## 通过 HTTP 提供 Tor 服务 {#http}
尽管通过https提供你的Tor版Mastodon可能很诱人但对大多数人来说这不是一个好主意。请参阅Tor Project上的[这篇](https://blog.torproject.org/facebook-hidden-services-and-https-certs)博文了解为什么https证书无法增加价值。由于你无法获得onion域名的SSL证书当你尝试使用你的Mastodon时还会被证书错误所困扰。最近一位Tor开发者在[这里](https://matt.traudt.xyz/p/o44SnkW2.html)阐述了为什么通过https提供Tor服务对大多数用例都没有好处的原因
本节假设你希望同时在 Tor 和公共互联网上公开你的实例
解决方法是通过http提供你的Mastodon服务但仅供Tor使用。这可以通过在Nginx配置文件中添加额外的设置来完成
虽然通过 HTTPS 提供 Mastodon 的 Tor 版本看起来很诱人但这并不总是理想的选择。HTTPS 证书主要对能够使用自己的公司信息生成证书的大公司有用。没有证书颁发机构(CA)能[免费](https://community.torproject.org/onion-services/advanced/https/)提供它们Tor 项目的[一篇博客文章](https://blog.torproject.org/facebook-hidden-services-and-https-certs)也解释了为什么 HTTPS 证书对安全性并没有真正的好处。但另一方面Mastodon 使用了大量使用到 HTTPS 的重定向,有经过验证的证书可能会使你的用户更容易在 Tor 上使用你的实例,而无需手动删除 URL 中的 `https://` 前缀
```text
在本节中,我们将介绍如何通过 HTTP 提供 Mastodon 实例,但仅限于 Tor。这可以通过在现有 Nginx 配置前添加额外配置来实现。
```nginx
server {
listen 80;
server_name mastodon.qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7qKnFwnNH2oH4QhQ7CoRf7HYj8wCwpDwsa8ohJmcPG9JodMZvVA6psKq7.onion;
@ -132,11 +137,11 @@ server {
}
```
你位于 `/var/lib/tor/hidden_service/hostname` 文件中的长hash替换上文中提供的
`/var/lib/tor/hidden_service/hostname` 文件中的 Tor 域名替换这里提供的长哈希值。这也应该反映在 snippets 文件中的 `Onion-Location` 头中
请注意onion域名已经被附加了“mastodon.”前缀。你的Tor地址充当通配符域名。所有的子域名都将被路由你可以配置你的Nginx来响应你想要的任何子域名。如果你不想在你的tor域名上托管任何其他服务你可以省略子域名或者选择一个不同的子域名。
注意洋葱主机名前面加了 "mastodon."。你的 Tor 地址充当通配符域名。所有子域名都会被路由,你可以配置 Nginx 响应你想要的任何子域名。如果你不希望在 Tor 地址上托管任何其他服务,可以省略子域名,或选择不同的子域名。
这里你就可以看出移动你的mastodon配置到不同文件的好处了。如果不移动的话你的所有配置都必须粘贴至两个地方任何对你配置的改动你都必须同时修改两个地方
现在你可以看到将 mastodon 配置移动到不同文件的好处。如果不这样做,所有配置都必须复制到两个地方。对配置的任何更改都必须在两个地方进行
重启你的Web服务器。
@ -144,10 +149,11 @@ server {
service nginx restart
```
## 陷阱 {#gotchas}
## 注意事项 {#gotchas}
你需要注意一些事情。某些重定向会将你的用户跳转至https。他们必须手动把URL替换成http才能继续。
你需要注意几点事项:
许多的资源诸如图片将仍然从常规非Tor域名加载。问题的严重性很大程度上取决于用户的谨慎程度。
- 如前所述Mastodon前端的某些URL会强制用户使用HTTPS URL。他们必须手动将URL替换为HTTP才能继续。
- 各种资源,如图像,仍将通过你常规的明网域名提供。这可能会成为问题,具体取决于你的用户希望、尝试或需要多高的隐私程度。
{{< translation-status-zh-cn raw_title="Hidden services" raw_link="/admin/optional/tor/" last_tranlation_time="2020-05-04" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
{{< translation-status-zh-cn raw_title="Onion services" raw_link="/admin/optional/tor/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,20 +1,24 @@
---
title: 准备你的
title: 准备你的服务
menu:
docs:
weight: 10
parent: admin
---
如果你正在设置一台全新的机器,推荐你首要完成安全设置。以下内容假定你运行 **Ubuntu 18.04**
如果你正在设置一台全新的服务器,建议你首先进行安全设置。假设你运行的是**Ubuntu 22.04**
## 禁止密码登录SSH仅允许密钥登录
## 禁用基于密码的 SSH 登录(仅限密钥)
首先,请确保你实际上是通过密钥而不是通过密码登录到服务器的,否则这将使你无法登录。许多托管服务提供商支持上传公钥并自动为新机器设置基于密钥的root登录。
首先,你需要确保自己现在已经是在使用密钥而非密码登录服务器,否则,这将使你无法登录。许多托管提供商支持上传公钥,并自动为新机器设置基于密钥的 root 登录。
编辑 `/etc/ssh/sshd_config` 并找到 `PasswordAuthentication`。确保它已被去除注释并被设为 `no`。如果你做了任何改动,请重启 sshd。
编辑 `/etc/ssh/sshd_config` 并找到 `PasswordAuthentication`。确保它已取消注释并设置为 `no`。做出更改后请重启sshd
## 更新系统
```bash
systemctl restart ssh.service
```
## 更新系统包
```bash
apt update && apt upgrade -y
@ -22,7 +26,13 @@ apt update && apt upgrade -y
## 安装 fail2ban 以阻止重复登录尝试
编辑 `/etc/fail2ban/jail.local` 并添加以下内容:
首先安装fail2ban
```bash
apt install fail2ban
```
编辑 `/etc/fail2ban/jail.local` 并在其中填入以下内容:
```text
[DEFAULT]
@ -32,66 +42,110 @@ sendername = Fail2Ban
[sshd]
enabled = true
port = 22
[sshd-ddos]
enabled = true
port = 22
mode = aggressive
```
最后重启fail2ban
最后,重启 fail2ban
```bash
systemctl restart fail2ban
```
## 安装防火墙并只暴露SSH、HTTP、HTTPS端口
## 安装防火墙并只允许 SSH、 HTTP 和 HTTPS 端口
首先,安装 iptables-persistent。在安装期间,它将询问你是否保留现有规则
首先,安装 iptables-persistent。在安装过程中,它会询问你是否要保留当前规则——选择拒绝
```bash
apt install -y iptables-persistent
```
编辑 `/etc/iptables/rules.v4`添加如下内容:
编辑 `/etc/iptables/rules.v4`在其中填入以下内容:
```text
*filter
# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
# 允许所有回环(lo0)流量,拒绝所有不通过 lo0 接口访问 127/8 地址段的流量
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# Accept all established inbound connections
# 接受所有已建立的入站连接
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow all outbound traffic - you can modify this to only allow certain traffic
# 允许所有出站流量 - 你可以修改此规则以实现只允许特定流量
-A OUTPUT -j ACCEPT
# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
# 允许来自任何地方的 HTTP 和与HTTPS 连接(网站和 SSL 服务的标准端口)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allow SSH connections
# The -dport number should be the same port number you set in sshd_config
# (可选)允许来自任何位置的 HTTP/3 连接
-A INPUT -p udp --dport 443 -j ACCEPT
# 允许 SSH 连接
# 这里的端口号应该与你在 sshd_config 中设置的端口号一致
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# Allow ping
# 允许 ping 请求
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# Log iptables denied calls
# 允许目标不可达消息,这里类型 4(需要分片)的消息对于 PMTUD (路径 MTU 发现)功能至关重要
-A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT
# 记录被 iptables 拒绝的请求
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Reject all other inbound - default deny unless explicitly allowed policy
# 拒绝所有其他入站请求 - 默认拒绝策略,除非明确允许
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT
```
iptables-persistent 将在机器启动时自动加载配置。但是由于我们现在不会立刻重启,我们需要第一次手动加载它
通过使用 iptables-persistent 进行配置,该配置将在启动时加载。但由于我们现在不重启,所以需要手动加载一次
```bash
iptables-restore < /etc/iptables/rules.v4
```
{{< translation-status-zh-cn raw_title="Preparing your machine" raw_link="/admin/prerequisites/" last_tranlation_time="2020-05-04" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
如果你的服务器也可以通过 IPv6 访问,编辑`/etc/iptables/rules.v6`并添加以下内容:
```text
*filter
# 允许所有本地回环(lo0)流量,并拒绝所有不通过 lo0 接口访问 127/8 地址段的流量
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d ::1/128 -j REJECT
# 接受所有已建立的入站连接
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允许所有出站流量 - 你可以修改此规则以实现只允许特定的流量
-A OUTPUT -j ACCEPT
# 允许来自任何位置的 HTTP 和 HTTPS 连接(网站和 SSL 服务的标准端口)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# (可选) 允许来自任何位置的 HTTP/3 连接
-A INPUT -p udp --dport 443 -j ACCEPT
# 允许 SSH 连接
# 这里的端口号应与 sshd_config 中设置的端口号一致
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# 允许 ping
-A INPUT -p icmpv6 -j ACCEPT
# 记录被 iptables 拒绝的请求
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# 拒绝所有其他入站连接 - 默认拒绝策略,除非明确允许
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT
```
与 IPv4 规则类似,你可以这样手动加载它:
```bash
ip6tables-restore < /etc/iptables/rules.v6
```
{{< translation-status-zh-cn raw_title="Preparing your machine" raw_link="/admin/prerequisites/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -0,0 +1,100 @@
---
title: 用户组
description: 通过管理员仪表板管理用户组。
menu:
docs:
parent: admin
---
# 用户组 {#roles}
数据库初始化时,用户组是从[`~/config/roles.yml`](https://github.com/mastodon/mastodon/blob/main/config/roles.yml)中的值派生的。
{{< page-ref page="entities/Role" >}}
生成的[默认用户组](#default-roles)有`所有者``管理员``协管员`
可以使用*用户组*(`/admin/roles`)页面上的[添加用户组](#add-role)来创建用户组及其属性。
![](/assets/admin-roles-ui.png)
可以使用[编辑用户组](#edit-role)功能更改现有用户组的属性。
## 默认用户组 {#default-roles}
### 基础用户组(*默认权限* {#default-base-role}
影响所有用户,包括没有分配用户组的用户。
此用户组唯一可修改的权限标识是**邀请用户**。启用此权限允许所有用户发送邀请。
基础用户组的优先级为`0`,此值不能更改。
### 所有者 {#default-owner-role}
被分配了**管理员**权限标识的用户组,绕过所有权限检查。具有所有者用户组的用户拥有每一个[权限标识](/entities/Role/#permission-flags)。
可以更改该用户组的*名称*、*徽章颜色*和*显示徽章*属性。该用户组的权限不能被编辑/撤销。
所有者用户组具有最高的[优先级](#role-priority)(`1000`)。所有者可以修改任何其他用户组的属性。创建的用户组不能超越所有者用户组,因为新的和现有用户组的[用户组优先级](#role-priority)必须 <= `999`
### 管理员 {#default-admin-role}
被分配了所有**审核**和**管理**权限标识的用户组。
此用户组的**DevOps**权限标识默认禁用,但可以由**所有者**(或具有更高优先级的自定义用户组)启用。
可以更改该用户组的*名称*、*徽章颜色*和*显示徽章*属性。
管理员用户组的优先级为`100`
### 协管员 {#default-moderator-role}
被分配了某些**审核**权限标识的用户组。这些权限标识包括...
- **查看仪表板**
- **查看审计日志**
- **管理用户**
- **管理举报**
- **管理分类**
可以更改该用户组的*名称*、*徽章颜色*和*显示徽章*属性。
协管员用户组的优先级为`10`
## 添加用户组 {#add-role}
`admin/roles/new`页面允许创建自定义用户组。
![](/assets/admin-roles-new-ui.png)
### 输入字段 {#add-role-input-fields}
{{< page-relref ref="entities/Role#name" caption="名称">}}
可以存在重复的用户组名称。它们在数据库中通过`id`区分,该`id`不能从网页界面设置。
{{< page-relref ref="entities/Role#color" caption="徽章颜色">}}
### 优先级 {#role-priority}
- 默认为`0`
- 不能 > `999`
- 可以是任何负整数值
- 两个用户组可以具有相同的优先级值
> "在特定情况下,由更高优先级的用户组决定冲突解决方式。某些操作只能对优先级较低的用户组执行。"
{{< page-relref ref="entities/Role#highlighted" caption="在账户页面显示用户组徽章">}}
{{< page-relref ref="entities/Role#permissions" caption="权限">}}
## 编辑用户组 {#edit-role}
![](/assets/admin-roles-edit-ui.png)
可以使用用户组列表中的*编辑*来编辑现有用户组及其属性。[输入字段](#add-role-input-fields)可以更改和保存,就像创建新用户组时一样。也可以使用此表单删除用户组。
![](/assets/admin-roles-edit-role-ui.png)
具有**管理用户组**权限的已登录用户始终能够看到每个用户组,但不能修改超过或等于其分配用户组[优先级](#role-priority)的用户组。
{{< translation-status-zh-cn raw_title="Roles" raw_link="/admin/roles/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,218 +1,283 @@
---
title: 伸缩你的服务器
descriptions: 为服务更多用户优化。
title: 扩大你的站点规模
descriptions: 为服务更多用户可以进行的优化。
menu:
docs:
weight: 100
parent: admin
---
## 并发管理 {#concurrency}
## 管理并发度 {#concurrency}
Mastodon有三种进程
Mastodon 有三种类型的进程:
* Web (Puma)
* Streaming API
* 后台进程 (Sidekiq)
- Web (Puma)
- 流式 API
- 后台处理 (Sidekiq)
### Web (Puma) {#web}
web进程处理绝大多数应用的短HTTP请求。以下环境变量可以控制它
Web 进程处理应用大部分的短周期 HTTP 请求。可通过以下环境变量控制并发度
* `WEB_CONCURRENCY` 控制worker进程数
* `MAX_THREADS` 控制每进程的线程数
- `WEB_CONCURRENCY` 控制工作进程的数量
- `MAX_THREADS` 控制每个进程的线程数量
线程共享其父进程的内存。不同的线程被分配了专有内存虽然他们通过copy-on-write共享了一些内存。数量较多的线程会先消耗掉你的CPU数量较多的进程会先消耗掉你的内存
线程共享其父进程的内存。不同的进程分配自己的内存,但通过写时复制共享一些内存。增加线程数量会优先耗尽你的 CPU而增加进程数量会先耗尽你的 RAM
这些数值会影响到可以同时处理多少HTTP请求。
上述变量的值可以影响同时能处理多少 HTTP 请求。
在吞吐量方面,多进程比多线程要好。
就吞吐量指标而言,增加进程数量比增加线程数量效果更好。
### Streaming API {#streaming}
### 流式 API {#streaming}
streaming API处理长HTTP连接与WebSockets连接通过这些连接用户可以接受到实时更新。以下环境变量可以控制它
流式 API 处理长周期 HTTP 和 WebSocket 连接,客户端通过这些连接接收实时更新。可通过以下环境变量控制并发度
* `STREAMING_CLUSTER_NUM` 控制worker进程数
* `STREAMING_API_BASE_URL` 控制streaming API的base URL
- `STREAMING_API_BASE_URL` 控制流式 API 的根 URL
- `PORT` 控制流式 API 服务器将监听的端口默认为4000。`BIND``SOCKET`环境变量也可以使用。
- 此外,流式 API 还使用共享的[数据库](/admin/config#postgresql)和 [Redis](/admin/config#redis) 环境变量。
一个进程可以处理相当数量的连接。 如果您愿意streaming API可以托管在其他子域上例如避免nginx代理连接开销
通过设置 `STREAMING_API_BASE_URL`,流式 API 可以使用不同的子域。这允许你为流式 API 和 Web API 请求使用不同的负载均衡器。然而,这也要求应用程序从[实例端点](/methods/instance/#v2)正确请求流式 API URL而不是假设它与 Web API 托管在同一域名上
### 后台进程 (Sidekiq) {#sidekiq}
流式 API 服务端的一个进程可以处理相当多的连接和吞吐量,但如果你发现单个进程无法处理你实例的负载,你可以通过改变每个进程的 `PORT` 号来运行多个进程然后使用nginx将流量负载均衡到每个实例。例如一个有大约 50000 个用户且月活跃用户为 10000 - 20000 个用户的社区,通常会有大约 800-1200 个并发流式 API 连接。
Mastodon许多任务都分配给后台进程以确保HTTP请求快速响应并防止HTTP请求中止影响到这些任务的执行。Sidekiq是单个进程具有可配置的线程数。
流式 API 服务端还在 `/metrics` 上暴露了一个 [Prometheus](https://prometheus.io/) 端点,提供许多指标帮助你了解 Mastodon 流式 API 服务器的当前负载,一些关键指标包括:
#### 线程数 {#sidekiq-threads}
- `mastodon_streaming_connected_clients`这是已连接客户端的数量按客户端类型标记websocket 或 eventsource
- `mastodon_streaming_connected_channels`:这是当前订阅的"频道"数量(注意由于我们内部"系统"频道的工作方式,这个数字比连接的客户端要高得多)
- `mastodon_streaming_messages_sent_total`:这是自上次重启以来发送给客户端的消息总数。
- `mastodon_streaming_redis_messages_received_total`:这是从 Redis pubsub 接收的消息数量,用于补充[直接监控Redis](https://sysdig.com/blog/redis-prometheus/)。
虽然web进程数与web线程数影响Mastodon实例响应终端用户分配给后台进程的线程数影响嘟文从作者分发至其他人的速度电子邮件花多长时间发完等等。
{{< hint style="info" >}}
运行的流式 API 服务端进程越多, PostgreSQL 上消耗的数据库连接就越多,所以你可能需要使用 PgBouncer如下文所述。
{{< /hint >}}
Sidekiq的线程数并不受环境变量控制但是可通过命令行参数控制例如
下面是一个 nginx 配置示例,用于将流量路由到三个不同的进程,分别运行在 `PORT` 4000、 4001 和 4002 上:
```text
upstream streaming {
least_conn;
server 127.0.0.1:4000 fail_timeout=0;
server 127.0.0.1:4001 fail_timeout=0;
server 127.0.0.1:4002 fail_timeout=0;
}
```
如果你使用分布式 systemd 文件,那么可以使用以下命令启动多个流式 API 服务端:
```bash
$ sudo systemctl start mastodon-streaming@4000.service
$ sudo systemctl start mastodon-streaming@4001.service
$ sudo systemctl start mastodon-streaming@4002.service
```
默认情况下, `sudo systemctl start mastodon-streaming` 只在端口4000上启动一个进程相当于运行 `sudo systemctl start mastodon-streaming@4000.service`
{{< hint style="warning" >}}
Mastodon 的早期版本有一个 `STREAMING_CLUSTER_NUM` 环境变量,该变量使流式 API 服务端使用集群,它启动多个工作进程并使用 Node.js 进行负载均衡。
上述配置与其他配置的交互方式使容量规划变得困难,在涉及到数据库连接和 CPU 资源时尤为如此。默认情况下,流式 API 服务端会消耗所有可用 CPU 上的资源,这可能会与服务器上运行的其他软件产生冲突。另一个常见问题是配置错误的 `STREAMING_CLUSTER_NUM` 导致因为每个集群工作进程打开连接池而耗尽数据库连接,因此 `STREAMING_CLUSTER_NUM``5``DB_POOL``10` 可能会消耗50个数据库连接。
现在,单个流式 API 服务端进程最多只会使用 `DB_POOL` 个PostgreSQL连接并且通过运行更多的流式 API 服务端实例来处理扩展。
{{< /hint >}}
### 后台处理 (Sidekiq) {#sidekiq}
Mastodon 中的许多任务都被委托给后台处理,以确保对 HTTP 请求的快速响应,并防止 HTTP 请求中止影响这些任务的执行。Sidekiq 是一个单一进程,具有可配置的线程数。
#### 线程数量 {#sidekiq-threads}
虽然 Web 进程中的线程数影响 Mastodon 实例对最终用户的响应速度,但分配给后台处理的线程数影响嘟文从作者传递给其他人的速度、邮件发送速度等。
线程数不是通过环境变量调整的,而是通过调用 Sidekiq 时的命令行参数调整,如下例所示:
```bash
bundle exec sidekiq -c 15
```
将启一个15线程的sidekiq进程。请注意每个线程都需要能够连接数据库这意味着数据库连接池应足够大以满足所有进程。数据库连接池的大小由`DB_POOL`环境变量控制,该变量必须至少与进程数同样大。
这将以 15 个线程启动 Sidekiq 进程。需要注意的是,每个线程都需要一个数据库连接,所以这需要一个大的数据库池。这个池的大小由 `DB_POOL` 环境变量管理,它应该设置为至少等于线程数的值
#### 队列 {#sidekiq-queues}
Sidekiq根据任务的重要性使用不同队列这里的重要性是指如果队列不工作其对本地用户体验的冲击有多大。按重要性降序排列
Sidekiq 使用不同的队列来处理不同重要性的任务,其中重要性是指如果队列不工作,对服务器本地用户体验的影响程度。队列按重要性降序列出如下
| 队列 | 重要性 |
| :--- | :--- |
| `default` | 影响本地用户的所有任务 |
| `push` | 推送消息至其它服务器 |
| `mailers` | 分发电子邮件 |
| `pull` | 从其它服务器拉取信息 |
| `scheduler` | 完成计划任务,例如更新当下流行标签及清理日志 |
`default`
: 影响本地用户的所有任务。
默认队列及其优先级存储于`config/sidekiq.yml`但可通过调用Sidekiq命令行覆盖例如
`push`
: 将负载传递到其他服务器。
`ingress`
: 传入的外站活动。优先级低于默认队列,以便在服务器负载过重时本站用户仍能看到他们的嘟文。
`mailers`
: 负责邮件的传递。
`pull`
: 较低优先级的任务,如处理导入、备份、解析嘟文串、删除用户、转发回复。
`scheduler`
: 处理定时任务,如刷新热门话题标签和清理日志。
默认队列及其优先级存储在 [config/sidekiq.yml](https://github.com/mastodon/mastodon/blob/main/config/sidekiq.yml) 中,但可以通过 Sidekiq 的命令行调用进行覆盖,例如:
```bash
bundle exec sidekiq -q default
```
仅运行`default`队列。
此命令将只运行 `default` 队列。
Sidekiq处理队列的方式是它首先检查第一个队列中的任务如果没有则检查下一个队列。这意味着如果第一个队列已满其他队列将延后。
Sidekiq 通过首先检查第一个队列中的任务来处理队列,如果没有找到,它会检查后续队列。因此,如果第一个队列过满,其他队列中的任务可能会遭遇延迟
作为一种解决方案可以启动为不同队列启动不同的Sidekiq进程以确保真正的并列执行例如使用不同Sidekiq参数创建多个systemd服务。
为队列创建不同的 Sidekiq 进程,可以实现真正的并行执行,例如为具有不同参数的 Sidekiq 创建多个 systemd 服务。
**请确保仅有一个`scheduler`队列!!**
{{< hint style="warning" >}}
你可以根据需要运行任意多的 Sidekiq 进程和线程,以有效处理运行中的作业,但是 `scheduler` 队列永远不应该在多个 Sidekiq 进程中同时运行。
{{< /hint >}}
## 使用PgBouncer进行事务池化 {#pgbouncer}
## 使用pgBouncer事务池 {#pgbouncer}
### 为什么你可能需要PgBouncer {#pgbouncer-why}
### 你为什么要用PgBouncer {#pgbouncer-why}
如果你开始耗尽可用的 PostgreSQL 连接默认为100个那么 PgBouncer 可能是一个好的解决方案。本文档描述了一些常见的问题,以及 Mastodon 的良好配置默认值。
如果开始耗尽可用的Postgres连接默认为100那PgBouncer可能是一个好方案。本文档将介绍Mastodon的一些常见陷阱及好的默认配置。
请注意你可以在管理界面的“PgHero”查看当前使用了多少Postgres连接。通常Mastodon使用Puma、Sidekiq、streaming API三者线程数总和的连接数。
在 Mastodon 中具有 `DevOps` 权限的用户可以通过管理视图中的 PgHero 链接监控当前 PostgreSQL 连接的使用情况。通常,打开的连接数等于 Puma、Sidekiq 和流媒体 API 中的线程总数。
### 安装PgBouncer {#pgbouncer-install}
Debian和Ubuntu
Debian 和 Ubuntu 上
```bash
sudo apt install pgbouncer
```
### 配置PgBouncer {#pgbouncer-config}
### 配置 PgBouncer {#pgbouncer-config}
#### 设置密码 {#pgbouncer-password}
首先如果你的Postgres中`mastodon`帐户没有设置密码的话,你需要设置一个密码。
First off, if your `mastodon` user in PostgreSQL is set up without a password, you will need to set a password.
首先,如果你的 PostgreSQL 中的 `mastodon` 用户没有设置密码,你需要设置一个密码。
下面是如何重置密码
以下是重置密码的方法
```bash
psql -p 5432 -U mastodon mastodon_production -w
```
之后很显然使用一个与单词“password”不同的密码):
然后(显然,此处应该使用不同于 "password" 的密码):
```sql
ALTER USER mastodon WITH PASSWORD 'password';
```
然后输入 `\q` 退出。
然后使用 `\q` 退出。
#### 配置userlist.txt {#pgbouncer-userlist}
#### 配置 userlist.txt {#pgbouncer-userlist}
编辑 `/etc/pgbouncer/userlist.txt`
只要稍后你在 pgbouncer.ini 中指定一个用户名/密码userlist.txt文件中的值*不必*与真实PostgreSQL用户相同。你可以随意设定用户名和密码但是为方便起来你可以重用“真实”的凭证。添加`mastodon`帐户至`userlist.txt`
只要你在稍后的 `pgbouncer.ini` 中指定了用户/密码, `userlist.txt` 中的值就不必与真实的 PostgreSQL 用户组对应。你可以任意定义用户和密码,但为了简单起见,你可以重用"真实"的凭证。将 `mastodon` 用户添加到 `userlist.txt`
```text
"mastodon" "md5d75bb2be2d7086c6148944261a00f605"
```
这里我们使用md5格式这里的md5密码就是字符串`密码 + 用户名`的md5值附加上`md5`。例如:为了获得用户名为`mastodon`密码为`password`的散列值,你可以这样做
这里我们使用 md5 方案,其中 md5 密码只是 `password + username` 的 md5sum前面加上字符串 `md5`。例如,为用户 `mastodon` 和密码 `password` 生成哈希
```bash
# ubuntu, debian, etc.
# ubuntu, debian
echo -n "passwordmastodon" | md5sum
# macOS, openBSD, etc.
# macOS, openBSD
md5 -s "passwordmastodon"
```
然后`md5`添加至开头
然后只需在开头添加 `md5`
也可以创建一个`pgbouncer`管理帐户以登入查看PgBouncer管理数据库。下面是一个`userlist.txt`文件的例子
还需要创建一个 `pgbouncer` 管理员用户来登录 PgBouncer 管理数据库。这里是一个示例 `userlist.txt`
```text
"mastodon" "md5d75bb2be2d7086c6148944261a00f605"
"pgbouncer" "md5a45753afaca0db833a6f7c7b2864b9d9"
```
以上两个帐户密码者是`password`
上述两个示例中的密码都为 `password`
#### 配置 pgbouncer.ini {#pgbouncer-ini}
编辑 `/etc/pgbouncer/pgbouncer.ini`
`[databases]`行下列出你想连接的Postgres数据库。这里PgBouncer将使用同样的用户名/密码和数据库名称连接下层Postgres数据库:
`[databases]` 部分添加一行,列出你想连接的 PostgreSQL 数据库。这里我们只让 PgBouncer 使用相同的用户名/密码和数据库名来连接底层的 PostgreSQL 数据库:
```text
```ini
[databases]
mastodon_production = host=127.0.0.1 port=5432 dbname=mastodon_production user=mastodon password=password
```
`listen_addr``listen_port` 告诉 PgBouncer 从哪个地址/端口接收连接。默认值即可
`listen_addr``listen_port` 将告知 PgBouncer 接受哪个地址/端口的连接。默认值的效果已经较为理想
```text
```ini
listen_addr = 127.0.0.1
listen_port = 6432
```
`auth_type`设为`md5`(假定你在`userlist.txt`使用md5格式):
`auth_type` 设为 `md5`(假设你在 `userlist.txt` 中使用了 md5 格式):
确保`pgbouncer`帐户为管理员:
```ini
auth_type = md5
```
**接下来的部分极其重要!** 默认连接池模式是基于连接session-based但是Mastodon需要基于事务transaction-based。换而言之当一个事务创建一个Postgres连接随之创建当事务完成该连接也随之结束。因此你需要把`pool_mode``session`改为`transaction`
确保 `pgbouncer` 用户是管理员
接下来,`max_client_conn`定义PgBouncer自身接受多少连接`default_pool_size`限制后台开启多少Postgres连接。在PgHero显示的连接数将与`default_pool_size`数目一致因为它不知道PgBouncer。
```ini
admin_users = pgbouncer
```
使用默认值启动即可,你可以随后调大他们:
Mastodon 需要不同于默认的基于会话的池化模式。具体而言,它需要基于事务的池化模式。这意味着 PostgreSQL 连接在事务开始时建立,在事务完成时终止。因此,必须将 `pool_mode` 设置从 `session` 更改为 `transaction`
```text
```ini
pool_mode = transaction
```
接下来, `max_client_conn` 定义 PgBouncer 本身将接受多少个连接,而 `default_pool_size` 限制了底层会开启多少个 PostgreSQL 连接。(在 PgHero 中举报的连接数将对应于 `default_pool_size`,因为它不知道 PgBouncer 的存在)。
默认值可以开始,之后你可以随时增加它们:
```ini
max_client_conn = 100
default_pool_size = 20
```
完成更改后不要忘记重载reload或重启restartpgbouncer
修改完成后,不要忘记重新加载或重新启动 PgBouncer
```bash
sudo systemctl reload pgbouncer
```
#### 调试,确保一切正常 {#pgbouncer-debug}
#### 调试并确认一切正常 {#pgbouncer-debug}
你应该能像连接Postgres一样连接PgBouncer
你应该能够像连接 PostgreSQL 那样连接到 PgBouncer
```bash
psql -p 6432 -U mastodon mastodon_production
```
然后使用你的密码登录。
然后使用你的密码登录。
也可以检查PgBouncer日专就像这样
还可以这样检查 PgBouncer 日志
```bash
tail -f /var/log/postgresql/pgbouncer.log
```
#### 配置 Mastodon 以连接 PgBouncer {#pgbouncer-mastodon}
#### 配置 Mastodon 与 PgBouncer 通信 {#pgbouncer-mastodon}
首先,确保`.env.production`文件这样设置
在你的 `.env.production` 文件中,首先确保配置了
```bash
PREPARED_STATEMENTS=false
```
因为我们使用基于事务transaction-based的连接池我们不能使用参数化查询prepared statement
由于我们使用基于事务的池化,我们不能使用预处理语句
接下来,配置Mastodon使用6432端口PgBouncer而不是5432端口PostgreSQL就可以了:
接下来,配置 Mastodon 使用端口 6432PgBouncer而不是 5432PostgreSQL之后你应该就可以开始运行了:
```bash
DB_HOST=localhost
@ -223,18 +288,18 @@ DB_PORT=6432
```
{{< hint style="warning" >}}
你不能使用pgBouncer来执行 `db:migrate` 操作。但是这个问题很容易解决。如果你的postgres和pgBouncer位于同一台主机只需要在执行任务时与 `RAILS_ENV=production` 一同定义 `DB_PORT=5432` 就可以了,例如:`RAILS_ENV=production DB_PORT=5432 bundle exec rails db:migrate`(如果主机不同,你也可以指定`DB_HOST`等)
PgBouncer 不能用于执行 `db:migrate` 任务,但这很容易解决。如果你的 PostgreSQL 和 PgBouncer 在同一主机上,可以简单地在调用任务时定义 `DB_PORT=5432``RAILS_ENV=production`,例如: `RAILS_ENV=production DB_PORT=5432 bundle exec rails db:migrate` (如果不同,你也可以指定 `DB_HOST` 等)
{{< /hint >}}
#### 管理 PgBouncer {#pgbouncer-admin}
最简单的重启方法:
最简单的重启方法
```bash
sudo systemctl restart pgbouncer
```
但如果你设定了PgBouncer管理员帐户你也可以用管理员帐户连接:
但如果你已经设置了 PgBouncer 管理员用户,你也可以以管理员身份连接:
```bash
psql -p 6432 -U pgbouncer pgbouncer
@ -246,22 +311,131 @@ psql -p 6432 -U pgbouncer pgbouncer
RELOAD;
```
使用 `\q` 退出。
然后使用 `\q` 退出。
## 单独的Redis缓存 {#redis}
## 针对缓存分离Redis {#redis}
Redis被广泛使用于应用但是某些用途比其他用途更重要。主页时间轴、列表时间轴、Sidekiq队列还有streaming API都是由Redis支持的这些是你不希望丢失的重要数据尽管丢失了也能存活不像PostgreSQL数据库的丢失——永远不要丢失PostgreSQL数据库。然而Redis也被用于易失性缓存。如果你正处于扩展阶段担心你的Redis能否处理所有事情你可以使用一个不同的Redis数据库来做缓存。在环境变量中你可以指定 `CACHE_REDIS_URL` 或分离形式,就像 `CACHE_REDIS_HOST``CACHE_REDIS_PORT`等等。未指定部分将会回落至没有前缀的相同设定值
Redis 在整个应用中被广泛使用,但有些用途比其他用途更重要。主页订阅、列表订阅、 Sidekiq 队列以及流式 API 都由 Redis 支持,这些是你不想丢失的重要数据(虽然与比不可丢失的 PostgreSQL 数据库不同,丢失这些数据也可以恢复)
至于Redis数据库配置基本上你可以去除后台保存至磁盘因为重启致使数据丢失也没关系你可以以此节省一些磁盘I/O。你还可以添加最大内存限制和 key eviction policy对于这部分请参阅这个指南[Using Redis as an LRU cache](https://redis.io/topics/lru-cache)
Redis 也用于易失性缓存。如果你正在扩展站点规模,并担忧 Redis 处理负载的能力,你可以专门为缓存分配一个单独的 Redis 数据库。要做到这一点,请在环境中设置 `CACHE_REDIS_URL`,或者定义单独的组件如 `CACHE_REDIS_HOST``CACHE_REDIS_PORT`
## 只读副本Read-replicas {#read-replicas}
未指定的组件将默认为没有 `CACHE_` 前缀的值。
为了减轻你的Postgresql服务器负担你可以使用热流复制hot streaming replication只读副本read replica。有关示例请参见[该指南](https://cloud.google.com/community/tutorials/setting-up-postgres-hot-standby)。你可以给以下Mastodon用途使用副本replica
在配置用于缓存的 Redis 数据库时,可以禁用后台保存到磁盘的功能,因为在重启时数据丢失不是很关键,这可以节省一些磁盘 I/O。此外考虑设置最大内存限制和实现键驱逐策略。有关这些配置的更多详细信息请查看此指南[使用 Redis 作为 LRU 缓存](https://redis.io/topics/lru-cache)
* streaming API 服务器无需写入因此你可以将其直接使用副本replica。但由于 streaming API 服务器不经常查询数据库,这样的优化影响很小。
* 使用 Makara 驱动 web 与 sidekiq 进程这样可以实现从主primary数据库写从副本replica读。让我们开始吧。
## 针对 Sidekiq 分离 Redis {#redis-sidekiq}
编辑 `config/database.yml` 文件,将 `production` 替换为如下内容:
Redis 在 Sidekiq 中用于跟踪其锁和队列。尽管总体上性能提升不是很大,但一些实例可能会受益于为 Sidekiq 单独设置 Redis 实例。
在环境文件中,你可以指定 `SIDEKIQ_REDIS_URL` 或单独的部分如 `SIDEKIQ_REDIS_HOST``SIDEKIQ_REDIS_PORT` 等。未指定的部分回退到不带 `SIDEKIQ_` 前缀的相同值。
创建一个单独的 Redis 实例用于 Sidekiq 相对简单:
首先复制默认的 redis systemd 服务:
```bash
cp /etc/systemd/system/redis.service /etc/systemd/system/redis-sidekiq.service
```
`redis-sidekiq.service` 文件中,更改以下值:
```bash
ExecStart=/usr/bin/redis-server /etc/redis/redis-sidekiq.conf --supervised systemd --daemonize no
PIDFile=/run/redis/redis-server-sidekiq.pid
ReadWritePaths=-/var/lib/redis-sidekiq
Alias=redis-sidekiq.service
```
为新的 Sidekiq Redis 实例复制 Redis 配置文件:
```bash
cp /etc/redis/redis.conf /etc/redis/redis-sidekiq.conf
```
在复制后的 `redis-sidekiq.conf` 文件中,更改以下值:
```bash
port 6479
pidfile /var/run/redis/redis-server-sidekiq.pid
logfile /var/log/redis/redis-server-sidekiq.log
dir /var/lib/redis-sidekiq
```
在启动新的 Redis 实例之前,创建一个数据目录:
```bash
mkdir /var/lib/redis-sidekiq
chown redis /var/lib/redis-sidekiq
```
启动新的 Redis 实例:
```bash
systemctl enable --now redis-sidekiq
```
更新你的环境变量,并添加以下行:
```bash
SIDEKIQ_REDIS_URL=redis://127.0.0.1:6479/
```
重启 Mastodon 以使用新的 Redis 实例。确保同时重启 web 和 Sidekiq否则其中一个仍将从错误的实例工作
```bash
systemctl restart mastodon-web.service
systemctl restart redis-sidekiq.service
```
## 用于高可用场景的 Redis Sentinel {#redis-sentinel}
如前所述, Redis 是 Mastodon 实例运行的关键部分。默认情况下,你的部署将使用单个 Redis 实例,或者如果你设置了缓存,则使用多个实例。但是,如果该实例宕机,也可能导致整个 Mastodon 实例宕机。为了缓解这个问题,可以使用 Redis Sentinel 来跟踪你的 Redis 实例,并在一个实例宕机时自动将客户端引导到新的主实例。你可以指定 `REDIS_SENTINELS`,这是 Mastodon 可以与之交互的 Sentinel 实例的 IP:Port 组合的以逗号分隔的列表,以确定当前的主 Redis 节点。你还需要在 `REDIS_SENTINEL_MASTER` 中指定你想要连接的主节点的名称。默认情况下, Sentinel 将在当前主节点无法访问一分钟后将其设置为宕机并选择新的主节点,但这可以根据你的设置进行配置。
所有与 sentinel 相关的变量也可以设置 `CACHE_``SIDEKIQ_` 前缀以便使用多个redis实例。
了解更多关于 Redis sentinel 的信息https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/
## 读副本 {#read-replicas}
为了减轻 PostgreSQL 服务器的负载,你可能希望设置热数据流式复制(读副本)。[参见此指南获取示例](https://cloud.google.com/community/tutorials/setting-up-postgres-hot-standby)。
### Mastodon >= 4.2
从 4.2 版本开始Mastodon 内置了对副本的支持。你可以为每个服务(包括 Sidekiq使用相同的配置当情况允许时某些查询将使用 Rails 内置的副本支持被定向到读副本。如果你的副本落后超过几秒钟,应用将停止向它发送查询,直到它赶上进度。
要配置读副本,请使用以下环境变量:
```
REPLICA_DB_HOST
REPLICA_DB_PORT
REPLICA_DB_NAME
REPLICA_DB_USER
REPLICA_DB_PASS
REPLICA_PREPARED_STATEMENTS
REPLICA_DB_TASKS
```
或者,如果你想使用同一个变量配置上述所有配置,也可以使用 `REPLICA_DATABASE_URL`
`REPLICA_DB_TASKS=false` 将使应用连接到副本数据库,但不执行任何数据库管理任务,如模型管理、迁移、种子管理等。默认情况下,它被设为 true。
作为可选选项,可用 `REPLICA_PREPARED_STATEMENTS` 覆盖 `PREPARED_STATEMENTS` 的值。如果未设置 `PREPARED_STATEMENTS`,默认为 true。
应用上述配置后,你应该开始看到对副本服务器的请求了!
### Mastodon <= 4.1
对于 4.2 之前的 Mastodon 版本,你可以通过以下方式在 Mastodon 中使用副本:
- 流式 API 服务端完全不发出写操作,所以你可以直接将其连接到副本(它无论如何也不经常查询数据库,所以这样做的影响很小)。
- 在 web 和 Sidekiq 进程中使用 Makara 驱动程序,使写操作发送到主数据库,而读操作发送到副本。让我们来讨论这个。
{{< hint style="warning" >}}
Sidekiq 进程当前不支持读副本,对 Sidekiq 进程使用读副本将导致作业失败和数据丢失。
{{< /hint >}}
你将需要为web进程使用单独的 `config/database.yml` 文件,并编辑它以替换 `production` 部分,如下所示:
```yaml
production:
@ -279,10 +453,27 @@ production:
url: postgresql://db_user:db_password@db_host:db_port/db_name
```
确保URL指向PostgreSQL服务器所在位置。你可以添加多个副本replica。你可以本地安装一个pgBouncer该pgBouncer可被配置为根据数据库名称连接两个不同服务器例如“mastodon”连接主服务器“mastodon_replica”连接副本服务器这样上面文件中的两个URL可以使用同样用户名、密码、主机、端口不同数据库名称。可能的设置有很多有关Makara的更多信息请参阅[其文档](https://github.com/taskrabbit/makara#databaseyml)。
确保 URL 指向 PostgreSQL 服务器的正确位置。你可以添加多个副本。你可以在本地安装一个 PgBouncer并配置其基于数据库名称连接到两个不同的服务器例如 "mastodon" 连接到主服务器, "mastodon_replica" 连接到副本因此在上面的文件中两个URL都会指向具有相同用户、密码、主机和端口但数据库名称不同的本地 PgBouncer。这样设置的可能性很多。有关 Makara 的更多信息,[请查看其文档](https://github.com/taskrabbit/makara#databaseyml)。
{{< hint style="warning" >}}
Sidekiq无法可靠的使用只读副本read-replicas因为即使是最微小的复制延迟也会导致查询不到相关纪录所致的任务失败。
确保 sidekiq 进程运行使用标准的 `config/database.yml`,以避免作业失败和数据丢失!
{{< /hint >}}
{{< translation-status-zh-cn raw_title="Scaling up your server" raw_link="/admin/scaling/" last_tranlation_time="2020-05-06" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
## 使用 Web 负载均衡器
像 DigitalOcean、AWS、Hetzner 等云提供商提供虚拟负载均衡解决方案,它们在多个服务器之间分配网络流量,但提供单一的公共 IP 地址。
可以扩展你的部署架构,在其中一个虚拟负载均衡器后面设置多个 web/Puma 服务器,以减少单个服务器被用户流量压垮的风险,帮助提供更一致的性能,并在进行维护或升级时减少停机时间。你应该咨询提供商的文档了解如何设置和配置负载均衡器,但要考虑到你需要配置负载均衡器来监控后端 web/Puma 节点的健康状况,否则你可能会向不响应的服务发送流量。
以下端点可用于监控此目的:
- **Web/Puma:** `/health`
- **流媒体API:** `/api/v1/streaming/health`
这两个端点都应返回HTTP状态码200以及文本`OK`作为结果。
{{< hint style="info" >}}
你也可以将这些端点用于第三方监控/警报工具的健康检查。
{{< /hint >}}
{{< translation-status-zh-cn raw_title="Scaling up your server" raw_link="/admin/scaling/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -1,25 +1,29 @@
---
title: 置你的新实例
description: 一些需要在安装完Mastodon做的事情
title: 置你的新实例
description: 安装 Mastodon 后需要做的事情
menu:
docs:
weight: 50
parent: admin
---
## 创建一个管理员帐户 {#admin}
## 创建管理员账户 {#admin}
### 通过浏览器 {#admin-gui}
### 在浏览器中创建 {#admin-gui}
通过浏览器完成帐户注册后,你需要使用命令行给你新创建的帐户以管理员特权。假设你帐户的用户名为`alice`
浏览器中注册后,你需要使用命令行给你新创建的账户授予管理员权限。假设你的用户名是 `alice`
```bash
RAILS_ENV=production bin/tootctl accounts modify alice --role Owner
```
### 通过命令行 {#admin-cli}
{{<hint style="warning">}}
在 Mastodon 4.0 之前,用户组被硬编码为 `user``moderator``admin` 之一。从 4.0 版本开始, Mastodon 有了一个可自定义的用户组系统,默认创建的用户组为 `Moderator``Admin``Owner`。自定义用户组的名称区分大小写。
{{</hint>}}
你可以使用命令行创建一个全新帐户。
### 从命令行 {#admin-cli}
你可以使用命令行创建一个新账户。
```bash
RAILS_ENV=production bin/tootctl accounts create \
@ -29,19 +33,19 @@ RAILS_ENV=production bin/tootctl accounts create \
--role Owner
```
一个随机密码将会显示在终端上
终端将输出随机生成的密码
## 填写站点信息 {#info}
登录后,打开**网站设置**页面。虽然从技术上来说无需填写这些信息,但对于操作服务器的人而言,这被认为是至关重要的。
登录后,转到**站点设置**页面(在**首选项** -> **管理**下)。理论上填写这些信息不是必须的,但对于运营一个面向人类的站点来说,这被认为是至关重要的。
| 设置 | 含 |
| 设置 | 含 |
| :--- | :--- |
| 用于联系的公开用户名 | 你的用户名,人们可以知道谁运营着这台服务器 |
| 用于联系的公开电子邮件地址 | 一个可以联系到你的电子邮件地址,可供那些帐户被锁或没有帐户的人使用 |
| 本站简介 | 你为什么启动这个站点?为谁运营?什么使它与众不同? |
| 本站详细介绍 | 你可以在此放置各种信息,但建议放置**行为准则**。 |
| 联系人用户名 | 你的用户名,让人们知道谁拥有此站点 |
| 业务邮箱 | 一个电子邮件地址,方便被锁定在账户之外的人或没有账户的人联系你 |
| 实例描述 | 你为什么创建这个站点?它适合谁?它有什么不同? |
| 自定义扩展信息 | 你可以在这里各种信息,但推荐放置**行为准则** |
填写完这些后,请点击“保存更改”
填写完这些信息后,点击"保存更改"
{{< translation-status-zh-cn raw_title="Setting up your new instance" raw_link="/admin/setup/" last_tranlation_time="2020-05-04" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
{{< translation-status-zh-cn raw_title="Setting up your new instance" raw_link="/admin/setup/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

File diff suppressed because it is too large Load diff

View file

@ -1,29 +1,53 @@
---
title: 故障分析
title: 故障排除
menu:
docs:
weight: 120
parent: admin
identifier: admin-troubleshooting
---
## **我看到一个故障页说一些东西出错了。我怎么找出哪里出错了**
## **我看到一个错误页面,上面说出了问题。我怎样才能找出是什么问题**
所有带堆栈追踪stack traces的错误信息都将会被写入系统日志。当使用systemd时可使用 `journalctl -u mastodon-web`(替换以相应的服务名) 来浏览每个服务的日志。当使用Docker时与之类似`docker logs mastodon_web_1`(替换以相应的容器名)
所有带有堆栈跟踪的错误消息都会写入系统日志。当使用 systemd 时,可以通过`journalctl -u mastodon-web`(请将 `mastodon-web` 替换为实际的正确服务名称)浏览每个 systemd 服务的日志。当使用 Docker 时,可以通过类似的命令 `docker logs mastodon_web_1`(请将 `mastodon_web_1` 替换为实际的正确容器名称)查看日志
服务端详细错误信息将*永不会*公开显示,因为它们可能会暴露你的内部设置,并为攻击者提供线索,让他们了解如何更好的入侵或如何更高效的滥用
服务器端错误的具体详情_永远不会_向公众显示因为它们可能会揭示你的内部设置情况并为攻击者提供如何入侵或更有效地滥用系统的线索
来自Mastodon web服务器的每一个响应都带有独一无二的请求IDrequest ID该ID也将反映在日志中。通过检查错误页的请求头你可以在日志中轻松找到与之对应的堆栈追踪stack traces
来自 Mastodon 网络服务器的每个响应都带有一个包含唯一请求 ID 的标头,这也将反映在日志中。通过检查错误页面的标头信息,你可以轻松在日志中找到相应的堆栈跟踪
## **升级新版本后,有些页面看起来很奇怪,就像它们含有未设置样式的元素一样。为什么**
## **我在日志中看不到太多内容。如何启用额外的日志/调试信息**
检查升级后,你是否运行 `RAILS_ENV=production bin/rails assets:precompile` 并重启Mastodon web 进程。因为这看起来像提供了过期的样式与脚本。这也有可能由于内存缺乏导致预编译失败很不幸webpack会占用大量内存。如果是这个原因请确保你已经分配了swap空间。另外也可以在另一台机器上预编译静态文件然后把它们复制至 `public/packs` 目录。
默认情况下,你的日志将显示 `info` 级别的日志记录。要查看更多调试消息,你可以修改 `.env.production` 文件以提高相关服务的级别:
## **升级新版本后,一些请求失败了,日志中的错误信息是 missing columns or tables。为什么**
- **Web/Sidekiq**将 `RAILS_LOG_LEVEL` 的值设为 `debug`,然后重启你正在尝试排除故障的服务。
- **Streaming**将 `LOG_LEVEL` 的值设为 `silly`,然后重启你正在尝试排除故障的服务。
检查升级后,你是否运行 `RAILS_ENV=production bin/rails db:migrate`。因为这看起来Mastodon代码访问了一个更新或更旧的数据库schema。如果你使用PgBouncer请确保此命令直接连接PostgreSQL因为PgBouncer不支持迁移过程中的锁表操作
有关这些选项的其他日志级别的更多信息,可以在[配置环境](https://docs.joinmastodon.org/admin/config)页面找到
## **我试图运行 `tootctl``rake`/`rails` 命令,但我得到 uninitialized constants 错误信息。哪里出错了?**
`debug``silly` 级别可能非常详细,因此在完成故障排除后,你应该注意将日志级别改回较低级别。
检查你是否在命令前使用 `RAILS_ENV=production` 指定正确的环境。默认情况下假定使用开发环境因此代码尝试加载开发相关gem。然而在生产环境中我们避免安装这些gem。这就是错误的来源。
## **升级到较新版本后,某些页面看起来很奇怪,例如出现了没有任何样式的元素。为什么?**
{{< translation-status-zh-cn raw_title="Troubleshooting errors" raw_link="/admin/troubleshooting/" last_tranlation_time="2020-05-08" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
请检查你是否在升级后运行了 `RAILS_ENV=production bin/rails assets:precompile`,并重启了 Mastodon 的 web 进程,因为它似乎正在提供过时的样式表和脚本。也可能是由于内存不足导致预编译失败,这是因为遗憾的是 webpack 非常消耗内存。如果是这种情况,请确保你分配了一些交换内存。或者,可以在不同的机器上预编译资源,然后复制 `public/packs` 目录。
## **升级到较新版本后,一些请求失败,日志显示关于缺少列或表的错误消息。为什么?**
检查你是否在升级后运行了 `RAILS_ENV=production bin/rails db:migrate`,因为看起来 Mastodon 的代码正在访问较新或较旧的数据库架构。如果你使用 PgBouncer请确保此命令直接连接到 PostgreSQL因为 PgBouncer 不支持迁移中使用的表锁定类型。
## **我尝试运行 `tootctl``rake`/`rails` 命令,但出现关于未初始化常量的错误。怎么回事?**
检查你是否在命令前指定了正确的环境变量 `RAILS_ENV=production`。默认情况下环境被假定为开发环境因此代码尝试加载与开发相关的gems。然而在生产环境中我们避免安装这些gems这就是错误的来源。
## **在执行 `RAILS_ENV=production bundle exec rails assets:precompile` 时遇到编译错误,但没有提供更多信息。如何修复?**
这通常是因为你的服务器在编译资源时内存不足。使用交换文件或增加交换空间以增加内存容量。运行 `RAILS_ENV=production bundle exec rake tmp:cache:clear` 清除缓存,然后执行 `RAILS_ENV=production bundle exec rails assets:precompile` 重新编译。确保在编译错误后清除缓存,否则会显示"一切正常"但资源保持不变。
## **我收到这个错误:`Read-only file system @ dir_s_mkdir`。为什么?**
默认情况下Mastodon使用[ systemd 的沙箱功能](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Sandboxing),这种方式不允许在 `/home/mastodon` 以外的位置执行写入。如果 Mastodon 安装在其他位置,你可能需要允许 `mastodon-sidekiq``mastodon-web` 写入自定义目录:
1. 在文件 `/etc/systemd/system/mastodon-sidekiq.service``/etc/systemd/system/mastodon-web.service` 中添加参数 `ReadWritePaths`。例如 - `ReadWritePaths=/example/mastodon/live`
2. 执行 `systemctl stop mastodon-sidekiq mastodon-web`
3. 执行 `systemctl daemon-reload`
4. 执行 `systemctl start mastodon-sidekiq mastodon-web`
{{< translation-status-zh-cn raw_title="Troubleshooting errors" raw_link="/admin/troubleshooting/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -0,0 +1,111 @@
---
title: 数据库索引损坏
description: 如何从数据库索引损坏中恢复。
menu:
docs:
weight: 10
parent: admin-troubleshooting
---
一个比较常见的配置问题可能导致整个数据库的索引损坏。本页尝试解释为什么会发生这种情况以及如何修复它。
## 语言数据与排序规则 {#explanation}
数据库中的文本值,如用户名或状态标识符,使用所谓的排序规则进行比较,这些规则定义了字符的排序方式和大小写转换方式。
在设置数据库时Mastodon 会使用数据库服务器的默认语言设置,包括默认排序规则,这通常由操作系统的设置决定。
不幸的是在2018年末一次 `glibc` 更新改变了许多区域设置的排序规则,这意味着使用受影响的语言设置的数据库现在会以不同方式排序文本值。
由于数据库索引依赖于它们所索引的值的排序的算法结构,一些索引可能会变得不一致。
更多信息https://wiki.postgresql.org/wiki/Locale_data_changes https://postgresql.verite.pro/blog/2018/08/27/glibc-upgrade.html
## 我是否受到这个问题的影响? {#am-i-affected}
如果你的数据库未使用 `C``POSIX` 作为其排序规则(你可以通过 `SELECT datcollate FROM pg_database WHERE datname = current_database();` 检查),
并且你曾经使用过 glibc 2.28 之前的版本,并且在更新到 glibc 2.28 或更新版本后没有立即重新索引你的数据库,那么你的索引可能不一致。
{{< hint style="info" >}}
你可能是因为 PgHero 警告"重复索引"而找到此页面的。虽然这类警告有时可能表明部署或更新 Mastodon 时出现问题,**但它们与数据库索引损坏无关,也不表明数据库存在任何功能问题**。
{{< /hint >}}
你可以使用 [PostgreSQL 的 `amcheck` 模块](https://www.postgresql.org/docs/10/amcheck.html)检查你的索引是否一致:作为数据库服务器的超级用户,连接到你的 Mastodon 数据库并执行以下命令(这可能需要一段时间):
```SQL
CREATE EXTENSION IF NOT EXISTS amcheck;
SELECT bt_index_check(c.oid)
FROM pg_index i
JOIN pg_class c ON i.indexrelid = c.oid
WHERE c.relname IN ('index_account_domain_blocks_on_account_id_and_domain',
'index_account_proofs_on_account_and_provider_and_username',
'index_accounts_on_username_and_domain_lower', 'index_accounts_on_uri',
'index_accounts_on_url', 'index_conversations_on_uri',
'index_custom_emoji_categories_on_name',
'index_custom_emojis_on_shortcode_and_domain',
'index_devices_on_access_token_id', 'index_domain_allows_on_domain',
'index_domain_blocks_on_domain', 'index_email_domain_blocks_on_domain',
'index_invites_on_code', 'index_markers_on_user_id_and_timeline',
'index_media_attachments_on_shortcode', 'index_preview_cards_on_url',
'index_statuses_on_uri', 'index_tags_on_name_lower',
'index_tombstones_on_uri', 'index_unavailable_domains_on_domain',
'index_users_on_email', 'index_webauthn_credentials_on_external_id'
);
```
如果出现错误,则你的数据库已损坏,需要修复。如果没有错误,你可能需要执行更复杂的检查以确保。
与之前的检查不同,这些更复杂的检查在运行时会锁表,从而影响实例的可用性。
```SQL
CREATE EXTENSION IF NOT EXISTS amcheck;
SELECT bt_index_parent_check(c.oid)
FROM pg_index i
JOIN pg_class c ON i.indexrelid = c.oid
WHERE c.relname IN ('index_account_domain_blocks_on_account_id_and_domain',
'index_account_proofs_on_account_and_provider_and_username',
'index_accounts_on_username_and_domain_lower', 'index_accounts_on_uri',
'index_accounts_on_url', 'index_conversations_on_uri',
'index_custom_emoji_categories_on_name',
'index_custom_emojis_on_shortcode_and_domain',
'index_devices_on_access_token_id', 'index_domain_allows_on_domain',
'index_domain_blocks_on_domain', 'index_email_domain_blocks_on_domain',
'index_invites_on_code', 'index_markers_on_user_id_and_timeline',
'index_media_attachments_on_shortcode', 'index_preview_cards_on_url',
'index_statuses_on_uri', 'index_tags_on_name_lower',
'index_tombstones_on_uri', 'index_unavailable_domains_on_domain',
'index_users_on_email', 'index_webauthn_credentials_on_external_id'
);
```
如果执行成功,没有返回错误,你的数据库应该是一致的,你可以安全地忽略 Mastodon 在运行 `db:migrate` 时发出的警告。
## 修复问题 {#fixing}
如果你受到影响但不采取行动,随着时间推移,你的数据库可能会变得越来越不一致。因此,尽快修复这个问题非常重要。
Mastodon 3.2.2 及更高版本附带了一个半交互式脚本,以尽可能良好的方式修复这些损坏。如果你使用的是早期版本,请先更新到 3.2.2。由于这些损坏的存在,可能在运行数据库迁移到 3.2.2 时会失败,但数据库应该会变成一个可以被 Mastodon 3.2.2 附带的维护工具恢复的状态。
在尝试修复数据库之前,**停止 Mastodon 并备份你的数据库**。然后,在**Mastodon 仍处于停止状态**的情况下,运行维护脚本:
```
RAILS_ENV=production bin/tootctl maintenance fix-duplicates
```
该脚本将遍历数据库以自动查找重复项并修复它们。在某些情况下,这些操作是破坏性的。在最具破坏性的情况下,你将被要求选择要保留的记录和要丢弃的记录。在所有情况下,搜索整个数据库中的重复项是一项极其耗时的操作。
{{< hint style="warning" >}}
在某些情况下,重复记录可能有无法调和的冲突(例如两个不同的本站用户共享相同的用户名)。在这些情况下,去重操作可能是**部分破坏性的**,你将被询问哪些记录保持不变,哪些记录将被更改。
因此,此脚本是半交互式的。在所有情况下,搜索整个数据库中的重复项是一项极其耗时的操作。
{{< /hint >}}
{{< hint style="danger" >}}
**由于维护脚本将暂时移除索引, Mastodon 必须在整个过程中完全停止,以防止出现其他重复项。**
{{< /hint >}}
## 避免问题
要避免这个问题,请在任何 libc 更新后立即重新索引你的数据库。
[SQL 命令 `REINDEX`](https://www.postgresql.org/docs/current/sql-reindex.html)
[`reindexdb` 命令行工具](https://www.postgresql.org/docs/current/app-reindexdb.html)
可能对此有用。
{{< translation-status-zh-cn raw_title="Database index corruption" raw_link="/admin/troubleshooting/index-corruption/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}

View file

@ -7,70 +7,80 @@ menu:
---
{{< hint style="info" >}}
一个新的Mastodon版本释出后它将出现在[GitHub releases页面](https://github.com/mastodon/mastodon/releases)。请注意:运行来自`main`分支的未释出代码,虽然可以进行,但不推荐这样做。
Mastodon 发布新版本时,它会出现在[ GitHub 发布页面](https://github.com/mastodon/mastodon/releases) 上。请注意,虽然可以运行 `main` 分支中的未发布代码,但不推荐这样做。
{{< /hint >}}
Mastodon版本与git tags一致。在尝试升级之前请至[GitHub releases页面](https://github.com/mastodon/mastodon/releases)查找所需版本。该页面包含了一个**更新日专**,其中描述你需要了解的所有差异,以及**特定的升级指令**。
### 自动更新验证 {#automated_checks}
开始之前,切换至`mastodon`用户:
从 v4.2.0 版本开始Mastodon 将自动检查可用更新并通知服务器上拥有 `DevOps` 权限的用户。
这通过每 30 分钟在后台获取 `https://api.joinmastodon.org/update-check?version=<current_version>` 来实现。 `current_version` 省略了构建元数据(如果版本字符串中含有`+`,则为第一个 `+` 之后的所有内容)。例如,如果你的版本是 `4.3.0-beta2+my-fork`Mastodon 将查询 `https://api.joinmastodon.org/update-check?version=4.3.0-beta2`
你可以通过设置 `UPDATE_CHECK_URL` 环境变量来更改 Mastodon 查询的 URL。你也可以通过将此环境变量设置为空字符串来完全禁用此行为但我们强烈建议不要这样做除非你通过其他方式关注 Mastodon 更新,因为 Mastodon 偶尔会发布必须及时应用的关键安全更新。
### 升级步骤
Mastodon 的发布版本对应 git 标签。在尝试升级之前,请在[ GitHub 发布页面](https://github.com/mastodon/mastodon/releases) 上查看所需的发布版本。该页面将包含**变更日志**,描述关于新版本不同之处的所有信息,以及**特定的升级说明**。
首先,切换到`mastodon`用户:
```bash
su - mastodon
```
并转至Mastodon根目录
并转到 Mastodon 根目录:
```bash
cd /home/mastodon/live
```
下载相应版本代码,这里假定版本为`v3.1.2`
下载发布版本的代码,假设版本为`v3.1.2`
```bash
git fetch --tags
git checkout v3.1.2
```
现在执行GitHub版本发布说明中的升级指令。因为不同的版本有不同的指令所以本页面将不包括任何指令
现在执行[ GitHub 上该版本的发行说明](https://github.com/mastodon/mastodon/releases) 中包含的升级说明。由于不同的发布版本需要不同的说明,我们不在此页面上包含任何说明
{{< hint style="info" >}}
从旧版本升级时,你可以安全的跳过中间版本。你无需单独检出他们。然而,你确实需要追踪每一个版本的升级指令。大多数指令都是重叠的,你只需要确保每条至少执行一次即可
从旧版本升级时,你可以安全地跳过中间版本。你不需要单独检出它们。但是,你需要跟随每个版本的说明。大多数说明的步骤是重复的,你只需确保至少执行一次所有内容
{{< /hint >}}
当你执行完版本发布说明中的指令后切换回root用户:
在执行完发布说明中的指令后,切回 root 用户:
```bash
exit
```
重启**后台worker**
重启**后台工作进程**
```bash
systemctl restart mastodon-sidekiq
```
并重载**web进程**
并重新加载 **Web 进程**
```bash
systemctl reload mastodon-web
```
{{< hint style="info" >}}
`reload`操作是零下线时间的重启restart也被称为“分阶段重启phased restart”。因此Mastodon升级通常不需要为计划下线而提前发布公告。罕见情况下你可以改用`restart`操作,但你的用户将感到(短暂的)服务中断。
`reload` 操作是一种零停机重启,也称为"分阶段重启"。因此Mastodon 升级通常不需要提前通知用户计划停机。在极少数情况下,你可以使用 `restart` 操作代替,但用户会感受到(短暂的)服务中断。
{{< /hint >}}
罕见情况下,**streaming API** 服务也会被更新并需要重启
**流式 API** 服务器也会更新并需要重启,这将导致所有已连接的客户端断开连接,可能增加服务器负载
```bash
systemctl restart mastodon-streaming
```
{{< hint style="danger" >}}
更新streaming API服务非常罕见在大多数版本中*不*需要重启它。重启streaming API将导致服务器负载增加因为断线的用户会尝试重连或改用REST API轮询。因此请尽量避免重启streaming API服务
重启流式 API 会增加服务器负载,因为断开连接的客户端会尝试重新连接或改为轮询 REST API所以尽可能避免这样做。
{{< /hint >}}
{{< hint style="success" >}}
**就这样!** 您现在正在运行新版本的Mastodon。
**以上就是所有步骤!**你现在正在运行新版本的 Mastodon。
{{< /hint >}}
{{< translation-status-zh-cn raw_title="Upgrading to a new release" raw_link="/admin/upgrading/" last_tranlation_time="2020-05-04" raw_commit="ad1ef20f171c9f61439f32168987b0b4f9abd74b">}}
{{< translation-status-zh-cn raw_title="Upgrading to a new release" raw_link="/admin/upgrading/" last_translation_time="2025-04-06" raw_commit="5e2b739ee193896bea937addc2843146ea0bc870">}}