跳到主要内容
  1. 所有文章/

低成本自托管 Mastodon 实例简明指南

·1997 字·约 4 分钟

前言 #

最近有点恶心 Twitter,在开始迁移到 Mastodon,记录下今天自托管 Mastodon 实例的过程。

准备 #

  1. 服务器配置 2 核心 4GB 以上,物理位置最好在海外
  2. 安装好最新的 Docker CE 和 Docker Compose 插件
  3. 一个托管在 Cloudflare 上的域名
  4. 一个用于 SMTP 发信的电子邮箱【可选】

预部署 #

SSH 登录服务器,准备路径

cd && \
mkdir -p container/mastodon && \
cd container/mastodon

获取 .env.production 环境变量模板

wget https://dejavu.moe/posts/selfhosted-mastodon-instance-with-docker/mastodon.env -O .env.production

sudo chown 991:991 .env.production

获取 docker-compose.yml 模板

wget https://dejavu.moe/posts/selfhosted-mastodon-instance-with-docker/docker-compose.yml.sample -O docker-compose.yml

准备容器映射目录

mkdir -p mastodon/public \
&& sudo chown -R 991:991 mastodon/public \
&& mkdir elasticsearch \
&& sudo chown 1000:1000 -R elasticsearch

提前拉取最新的 Docker 镜像备用

sudo docker compose pull

云存储 #

不建议将 Mastodon 的媒体和文件保存到服务器本机,备份起来会很麻烦。Mastodon 支持使用 S3 或兼容 S3 API 的对象存储,比如 MinIO, Cloudflare R2, Storj, Tebi.io…更多免费对象存储 在这里 查看。

这里以 Backblaze B2 为例,免费用户 10GB 对象存储,1GB 出站流量,兼容 S3 API,B2 和 Cloudflare 有「带宽联盟」豁免流量,对于单人 Mastodon 实例足够了。

Backblaze B2 注册帐号,新建 Bucket(存储桶)

Create Bucket
Create Bucket

记下 S3 Endpoint

S3 Endpoint
S3 Endpoint

接下来创建一个新的 Application Key

Application Key
Application Key

按照下图配置权限

Add Application Key
Add Application Key

记下 KeyID 和 applicationKey

S3 API
S3 API

在这个 Bucket 随便上传一个文件

Upload File
Upload File

点击上传的文件,可以看到 Friendly URL

Friendly URL
Friendly URL

在 Cloudflare DNS 解析里添加一条 CNAME 记录,指向 Friendly URL 的主机名(必须开启小云朵代理)

DNS CNAME
DNS CNAME

在 Cloudflare 规则选项卡里面的转换规则中,创建一条重写规则

Transform Rule
Transform Rule

编辑新创建的转换规则

Edit Transform Rule
Edit Transform Rule

重写资源路径

Rewrite URI
Rewrite URI

在规则设置里打开标准化传入

Standardization
Standardization

现在上传到 Backblaze B2 存储的资源可以通过自定义域名访问了,记得设置更长的浏览器缓存时间和边缘缓存时间。将 S3 API 相关配置写入环境变量文件 .env.production

vim .env.production

修改下面字段

# File Storage (optional)
# -----------------------
S3_ENABLED=true
S3_PROTOCOL=https  # S3 使用的协议
S3_ENDPOINT=https://s3.xxx.com  # S3 API Endpoint
S3_ALIAS_HOST=static.xxx.com  # 这里填写您的自定义域名(上面解析用于重写的那个)
S3_BUCKET=<Bucket 名称> # Bucket 名称
AWS_ACCESS_KEY_ID=<S3 API 兼容访问 KeyID>  # 对应 B2 KeyID
AWS_SECRET_ACCESS_KEY=<S3 API 兼容访问机密>  # 对应 B2 applicationKey

初始化 #

数据库 #

先查看当前路径

pwd
# 比如我的就是
/home/dejavu/container/mastodon

初始化数据库,数据库卷映射目录为

/home/dejavu/container/mastodon/postgres

下面的密码要记好1

sudo docker run --name postgres14 -v $(pwd)/postgres:/var/lib/postgresql/data -e POSTGRES_PASSWORD='数据库管理密码' --rm -d postgres:14-alpine

进入 PostgreSQL 控制台

sudo docker exec -it postgres14 psql -U postgres

然后执行下列 SQL 语句

#  PostgreSQL 控制台中执行命令
/* 创建名为 mastodon 的用户并设置密码*/
CREATE USER mastodon WITH PASSWORD '密码' CREATEDB;
/* 创建名为 mastodon 的数据库*/
CREATE DATABASE mastodon;
/* 列出当前数据库 */
\l
/* 连接 mastodon 数据库*/
\c mastodon;
/* 出现下面的提示 */
You are now connected to database "mastodon" as user "postgres".
/* 继续执行 */
CREATE extension pg_stat_statements;
/* 退出 PostgreSQL 控制台 */
\q

完成后停止 PostgreSQL 容器

sudo docker stop postgres14

机密信息 #

在「预部署」阶段的环境变量文件中,有四个机密信息

# Secrets
# -------
SECRET_KEY_BASE=<浏览器会话机密>
# MFA secret
OTP_SECRET=<多因素认证机密>
# -------

# Web Push
# --------
# Push notification private key
VAPID_PRIVATE_KEY=<推送通知私钥>
# Push notification public key
VAPID_PUBLIC_KEY=<推送通知公钥>

我们可以预先生成并保留备用

# 运行两次
# 一次作为 SECRET_KEY_BASE=<浏览器会话机密>
# 一次作为 OTP_SECRET=<多因素认证机密>
sudo docker compose run --rm web bundle exec rake secret

# 运行一次
# 包含 VAPID_PRIVATE_KEY=<推送通知私钥>
# 和 VAPID_PUBLIC_KEY=<推送通知公钥>
sudo docker compose run --rm web bundle exec rake mastodon:webpush:generate_vapid_key

将上面的信息写入环境变量文件

vim .env.production

环境变量 #

完成填写前面的环境变量2 ,比如 SMTP 发信配置。有关更多配置项的说明,请查看 Mastodon 文档。现在开始准备 Mastodon 的数据库

sudo docker compose run --rm -v $(pwd)/.env.production:/opt/mastodon/.env.production web bundle exec rake db:setup

完成后停止所有容器

sudo docker compose down

开始部署 #

先部署相关数据库服务,等待 10s 启动所有服务

sudo docker compose up -d db redis \
&& sleep 10s \
&& sudo docker compose up -d

完成后,在 Cloudflare Zero Trust 控制台添加一个 Tunnel,然后编辑公共主机名(用于 Mastodon 主页,建议裸域)

Mastodon Domain
Mastodon Domain

在这个 Tunnel 上再添加一个公共主机名,这个用于 Mastodon Stream API

Mastodon Stream Domain
Mastodon Stream Domain

现在尝试访问绑定的 Mastodon 主页域名,应该可以正常访问了,那就 OK 了,先不要急着注册用户

设置管理员 #

直接使用 tootctl 工具来设置 Mastodon 实例管理员,这个帐号我们之后可以直接使用

# 注意修改
# 管理员用户名 username
# 管理员用户的邮箱 me@xxx.com
sudo docker exec mastodon-web tootctl accounts create "username" --email "me@xxx.com" --confirmed --role Owner

# 输出:
OK
New password: "初始密码"

上面的初始密码只会显示一次,如果不幸忘记了3 ,可以重置用户密码

sudo docker exec mastodon-web tootctl accounts modify "username" --email "me@xxx.com" --reset-password

# 输出:
OK
New password: "新的密码"

完成 #

恭喜您!😎 您刚刚部署的 Mastodon 实例已经可以访问了,欢迎加入联邦宇宙!您也许想要看看 Mastodon 客户端

我的 Mastodon4 链接是 https://sink.love/@dejavu,欢迎关注 🥺

参考信息


  1. 数据库管理密码和数据库用户密码在此可以设置一样的,他们仅在 Docker 容器内部连接 ↩︎

  2. 还是修改 .env.production 文件 ↩︎

  3. 没错,就是我 😭 ↩︎

  4. 存储太小,所以不开放注册了 🤤 ↩︎

Dejavu Moe
作者
Dejavu Moe
Not for success, just for growing.