从源码以白名单模式部署Mastodon 4.x站点
这篇文章是在2C 4G Debian 11 x64下部署的,此时的mastodon版本为4.1.0。
以下命令均以一个非root但具有sudo权限的用户的身份执行。如果你想为Mastodon单独创建一个用户(此处用户名为mastodon),请执行:
sudo adduser --disabled-login mastodon
这个用户不需要sudo权限,因此,为系统安装软件包是,请切换至root用户(或为root用户再单开一个shell)
一、准备环境
1. 保持系统最新、安装必要软件包
sudo apt update sudo apt upgrade apt install -y curl wget gnupg apt-transport-https lsb-release ca-certificates
2. 安装Node 16.x
以下方法二选一:
(1)若要多版本共存,可使用Node版本管理工具,此处使用nvm:
(如果你为mastodon创建了专门的用户,此处记得用sudo su - mastodon切回mastodon用户)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash source ~/.bashrc nvm install --lts=gallium nvm use lts/gallium node -v
(2)直接添加apt源并安装:
sudo curl -sL https://deb.nodesource.com/setup_16.x | bash - sudo apt update sudo apt install node
3. 安装Postgresql和Redis
sudo wget -O /usr/share/keyrings/postgresql.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc sudo 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 sudo apt update sudo apt install postgresql redis-server
4. 补充安装Mastodon文档要求的其它包
sudo apt update sudo apt install -y \ imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core \ g++ libprotobuf-dev protobuf-compiler pkg-config nodejs gcc autoconf \ bison build-essential libssl-dev libyaml-dev libreadline6-dev \ zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev \ nginx redis-server redis-tools postgresql postgresql-contrib \ certbot python3-certbot-nginx libidn11-dev libicu-dev libjemalloc-dev
5. 安装Yarn
npm install --global yarn corepack enable yarn set version classic
6. 安装Ruby
此处直接采用官方文档中的版本管理方案,不再另外列出其它方案。如果你为mastodon创建了单独的用户,这一步需要切回mastodon用户操作。
cd 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_CONFIGURE_OPTS=--with-jemalloc rbenv install 3.0.4 rbenv global 3.0.4 gem install bundler --no-document
7. 创建数据库用户
sudo -u postgres psql
在输入下面的SQL语句时,请注意替换对应的用户名及密码。
CREATE USER mastodon PASSWORD 'XXXXXXX' CREATEDB; \q
二、部署Mastodon
如果你创建了单独的用户,此步需切至mastodon用户操作。
1. 拉取源码存储库
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)
2. 安装依赖
bundle config deployment 'true' bundle config without 'development test' bundle install -j$(getconf _NPROCESSORS_ONLN) yarn install --pure-lockfile
3. 生成配置
RAILS_ENV=production bundle exec rake mastodon:setup
按提示输入即可。这一步生成的是.env.productions文件,可参考下面内容交互式填写:注意,下面的内容仅列出rake mastodon:setup命令要求输入的内容
LOCAL_DOMAIN=xxx.closed.social # 本站域名 SINGLE_USER_MODE=false # 不启用单用户模式 DB_HOST=/var/run/postgresql # 保持默认即可,除非你改过 DB_PORT=5432 # 保持默认即可 DB_NAME=closed_social # 自行起名 DB_USER=mastodon # 与(一)中第7步用户名一致 DB_PASS=XXXXX # 与(一)中第七步密码一致 REDIS_HOST=localhost # 保持默认即可 REDIS_PORT=6379 # 保持默认即可 REDIS_PASSWORD= # 留空即可 S3_ENABLED=false # 暂不配置s3 SMTP_SERVER=smtp.xxx.xxx # SMTP服务可选择126/163/QQ等免费邮箱、腾讯企业邮箱(要求域名备案、有免费计划)、阿里云邮件服务(要求发件域名备案)等 SMTP其余配置根据个人情况填写 SMTP_AUTH_METHOD=plain # 默认值 SMTP_OPENSSL_VERIFY_MODE=peer # 默认值 SMTP_ENABLE_STARTTLS=auto # 默认值 SMTP_FROM_ADDRESS='闭社xx站 xxx@xxx.xxx' # 发件人名称不要含有特殊字符
这一步会提示创建管理员用户,请记下用户名和生成的初始密码。
【排错】如果连接数据库时遇到connection closed by peer之类的问题,请以root权限修改 /etc/postgresql/15/main/pg_hba.conf ,将其中Unix套接字的认证连接方式从peer改为scram-sha-256
# 更改前 local all all peer # 更改后 local all all scram-sha-256
然后
systemctl restart postgresql
4. 生成SSL证书
如果你使用closed.social域名,你需要联系域名所有者,如果你使用自己的域名,则可以按照自己觉得合适的方式生成。
免费证书推荐使用acme.sh:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E
5. 配置反代
此处使用Nginx,如果服务器还未安装Nginx,可直接从apt安装或添加第三方打包源后安装。Nginx安装过程略。
# 请把“/home/mastodon/live”替换为你拉取的Mastodon源码的绝对路径。 sudo cp /home/mastodon/live/dist/nginx.conf /etc/nginx/sites-available/mastodon sudo ln -s /etc/nginx/sites-available/mastodon /etc/nginx/sites-enabled/mastodon
编辑/etc/nginx/sites-available/mastodon:编辑要点:
(1)如果你修改了masdon web或streaming API的监听端口,请修改nginx文件中对应的upstream:
(2)注意修改两个server的server_name字段和root字段,server_name字段是你站点的域名,root字段是拉取的mastodon源码的绝对路径下的public目录。
(3)注意修改ssl_certificate和ssl_certificate_key字段为你的证书所在绝对路径,并确保Nginx所在的用户/用户组(均为www-data)对其具有读权限。
编辑完成后测试Nginx配置:
sudo nginx -t
无误后重启Nginx(因为需要加载新证书)
sudo systemctl restart nginx
6. 配置Systemd服务、启动Mastodon
请把“/home/mastodon/live”替换为你拉取的Mastodon源码的绝对路径。
cp /home/mastodon/live/dist/mastodon-*.service /etc/systemd/system/
请提前配置EDITOR变量或将其替换为你喜欢的编辑器
$EDITOR /etc/systemd/system/mastodon-*.service
编辑要点:
(1)每个文件的的User字段均要改为mastodon源码目录的所属用户,或你专门为mastodon新建的用户。
(2)每个文件的WorkingDirectory和ReadWritePaths(如果有)字段均要改为mastodon源码所在的绝对路径
(3)如果你要指定不同的监听端口,请修改对应的环境变量字段
(4)ExecStart字段中ruby运行环境的位置应修改为对应的用户(即:位置不一定是/home/mastodon/...)
启动并配置开机自启:
systemctl daemon-reload systemctl enable --now mastodon-web mastodon-sidekiq mastodon-streaming
如遇报错,可使用journalctl查找原因
三、配置Mastodon
1. 登录并修改管理员密码
这一步要求你的SMTP配置可用,如果你的SMTP还没配好,请到文档中寻找通过命令行修改密码的方法(可能只有重置密码的命令,我没有细看)。
2. 载入注册邮箱白名单及附加配置
在 .env.production 文件后酌情添加以下配置:
# 必须添加 # 1. 注册邮箱白名单 EMAIL_DOMAIN_ALLOWLIST=xxx.edu.cn|xiaoyou.xxx.cn|jiaozhigong.xxx.edu.cn # 2. 白名单模式(仅与指定实例互动) LIMITED_FEDERATION_MODE=true # 可选配置 # 1. 实例默认语言 DEFAULT_LOCALE=zh-CN # 2. 信任的反代IP(此处的配置包含了常用本地段及所有Cloudflare IP段) # 配置这个可以在后台看到真实用户IP # 如果你在本地用Nginx等进行反代后又套了一层Cloudflare反代,那么你可能还需要在Nginx里配置Cloudflare的IP段为信任代理源 TRUSTED_PROXY_IP=127.0.0.1/8,::1/128,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,fc00::/7,173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,2400:cb00::/32,2606:4700::/32,2803:f800::/32,2405:b500::/32,2405:8100::/32,2a06:98c0::/29,2c0f:f248::/32 # 3. Redis命名空间 # 如果你的redis中还存在其它项目,请使用 REDIS_NAMESPACE=mastodon_xxx
完成后,在Mastodon源码所在目录执行:
RAILS_ENV=production ./bin/tootctl domain purge --limited-federation-mode
然后重启所有mastodon服务。
3. 联动闭社实例
这里给出一份截止到目前的闭社实例列表:
#domain thu.closed.social tha.closed.social sjtu.closed.social umas.social fzu.closed.social mku.social njust.club s.ourneu.space smu.closed.social bjut.closed.social zzuli.closed.social nwpu.closed.social uestc.social
可以将其保存为一个文本文档,然后在首选项-运营-已知实例中导入。也可以逐个添加。
当你方实例和对方实例均添加完毕后,可主动搜索对方实例管理员账号,发送私信制造跨站联动。如果这些操作均能成功,就证明实例间可以正常通信。
4. 其它调优
(1)本机安全配置
建议关闭SSH密码登录(改为密钥登录)、安装防火墙并配置防火墙规则。还可以更改SSH端口。
(2)Postgres性能调优
参考官方文档给出的工具:https://pgtune.leopard.in.ua/#/
(3)开放部分API
目前版本中,LIMITED_FEDERATION_MODE禁用了对所有api的公开访问。这导致两个主要问题:
- 访问主页会报一堆401错误
- 部分APP登录会出现登陆失败或识别不出实例的情况
可尝试如下解决方案:
- 首先在网页端正常登录,或用其它方式拿到Mastodon的AccessKey
- 在浏览器或命令行中请求如下接口,将返回值分别保存至文件中:
https://your.domain/api/v1/instance https://your.domain/api/v2/instance
3. 编辑Nginx对应站点文件,添加如下伪静态规则:
location /api/v1/instance {
alias /path/to/v1_instance.json;
}
location /api/v2/instance {
alias /path/to/v2_instance.json;
}
重载nginx,即可基本解决问题。
这个方法的缺陷在于:无法实时更新实例人数。
另外,访问站点主页时还有两个API会报错,分别是/api/v1/trend/tags/ 和 /api/v1/instance/extended_description 。 理论上可参照此方法进行修改。
(3)S3
很多S3服务商为流量计价,如果有人恶意刷流量,可能会造成天价账单。
此处给出Cloudflare R2的S3配置,开通Cloudflare R2需要外币卡,但其仅按请求计费且提供10G免费额度,足够站点初期使用,速度方面尚可。
# 修改 .env.production # 修改内容 S3_ENABLED=true # 新增内容 S3_ALIAS_HOST=你的存储桶绑定的域名,可省略但建议配置 S3_BUCKET=存储桶名 S3_ENDPOINT=https://<你的cloudflare账户ID>.r2.cloudflarestorage.com/ AWS_ACCESS_KEY_ID=在R2 API页面生成的Access Key AWS_SECRET_ACCESS_KEY=在R2 API页面生成的Access Secret S3_PROTOCOL=https S3_PERMISSION=private
(4)CDN
直接回源源站并配置Access-Control-Allow-Origin头即可,也可手动将Mastodon源码内的Public文件夹托管至服务商,例如上传至另一个S3存储桶并绑定域名。
然后修改 .env.production
CDN_HOST=CDN域名
重启Mastodon的Web服务。
更新后不要忘了刷新CDN。
(5)Elasticsearch
Elasticsearch的部署效果是能为站点带来全文搜索,缺点在于内存开销巨大,请根据机器配置自我权衡。笔者目前没有配置,此处给出官方文档的配置步骤。
配置环境:
sudo apt install openjdk-17-jre-headless sudo wget -O /usr/share/keyrings/elasticsearch.asc https://artifacts.elastic.co/GPG-KEY-elasticsearch sudo 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 sudo apt update sudo apt install elasticsearch sudo systemctl daemon-reload sudo systemctl enable --now elasticsearch
安装两个中文分词插件:参见:
https://github.com/medcl/elasticsearch-analysis-ik#install
https://github.com/medcl/elasticsearch-analysis-stconvert/releases
安装完成后重启elasticsearch
编辑 .env.production:
ES_ENABLED=true ES_HOST=localhost ES_PORT=9200 # 可选配置 ES_USER=你在elasticsearch中的对应用户 ES_PASS=用户密码 ES_PREFIX=默认值跟随redis的命名空间前缀,可不管
修改索引相关代码:(如果你安装了中文分词)
参见:https://docs.joinmastodon.org/admin/optional/elasticsearch/#chinese-search-optimization
重启受影响服务:
sudo systemctl restart mastodon-sidekiq sudo systemctl reload mastodon-web
创建索引:(如果你创建了专门的用户,请切回对应用户)
在mastodon源码目录执行:
RAILS_ENV=production bin/tootctl search deploy