Oracle 给了我两个 1C 1G 的永久免费服务器,正好用来搭建 mastodon,也把 fuckyou.plus 这个域名用上。
mastodon 给出的 docker-compose.yml 里有三个服务,其中较为吃内存的是使用 ruby 编写的 web 和 sidekiq,streaming 用了 nodejs 所以在轻负载情况下占用的资源并不多。
为了最大化的降低这两个资源大户的需求,我寻求了 new bing 的帮助,知道了将 WEB_CONCURRENCY
设置为 0 的时候,Puma 将会从集群模式变为单进程模式。然后根据 mastodon 配置文档把 MAX_THREADS
设置为了 2,这是限制 Puma 进程最多只能有两个线程。再把 docker-compose.yml 里 sidekiq 的启动命令修改为 bundle exec sidekiq -c 1
,根据 mastodon 文档的说明这会让队列只运行一个线程。
到这里其实已经可以在一台 1C 1G 的服务器上运行 mastodon 了。只是我有两台,所以我将 sidekiq 的线程数量上调之后放到了另一台服务器单独运行,把 docker-compose.yaml 拆解为多个,一个里运行 web 和 streaming,它们和 postgresql、redis 以及前置的 caddy 反向代理服务器一起运行;一个运行 sidekiq。
version: '3'
services:
postgres:
image: postgres:14
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
healthcheck:
test: ['CMD', 'pg_isready', '-U', 'postgres']
volumes:
- ./data:/var/lib/postgresql/data
restart: always
version: '3'
services:
redis:
image: "redis:7-alpine"
command: /bin/sh -c "redis-server --requirepass $$REDIS_PASSWORD"
environment:
REDIS_PASSWORD: password
ports:
- "6379:6379"
volumes:
- ./data:/data
restart: always
version: '3'
services:
web:
image: ghcr.io/mastodon/mastodon:v4.2.1
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
healthcheck:
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
ports:
- '127.0.0.1:3000:3000'
volumes:
- ./public/system:/mastodon/public/system
streaming:
image: ghcr.io/mastodon/mastodon:v4.2.1
restart: always
env_file: .env.production
command: node ./streaming
healthcheck:
test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']
ports:
- '127.0.0.1:4000:4000'
version: '3'
services:
sidekiq:
image: ghcr.io/mastodon/mastodon:v4.2.1
restart: always
env_file: .env.production
command: bundle exec sidekiq -c 1
volumes:
- ./public/system:/mastodon/public/system
healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
执行步骤
git clone https://github.com/mastodon/mastodon
,复制 .env.production.sample 文件到 .env.production 并将WEB_CONCURRENCY=0
与MAX_THREADS=2
写入到头部。- 启动 postgresql 和 redis 服务。
- 运行
docker run --rm -it ghcr.io/mastodon/mastodon:v4.2.1 /bin/bash
- 在里面使用
bundle exec rake mastodon:setup
按照提示填入配置信息与数据库信息,并初始化数据库与管理员账号。 - 复制
bundle exec rake mastodon:setup
命令最终生成的对应配置文件字段到宿主机的 .env.production 文件中。
- 在里面使用
- 修改一些配置,例如
LOCAL_DOMAIN
、STREAMING_API_BASE_URL
,然后使用docker-compose up -d
启动 web 和 streaming 服务。 - 复制 .env.production 文件到另一台服务器放在 docker-compose.yml 同目录下,使用
docker-compose up -d
启动 sidekiq 服务。 - 配置 caddy 服务,并通过浏览器登录管理员账号进行站点配置。
其他配置技巧
来自其他服务器的缓存
mastodon 不允许你关闭来自其他服务器的缓存,而当我订阅中继服务器之后,三天时间创建了接近 10 Gb 的 S3 缓存,成本非常高。
偶然的巧合下,我发现把 sidekiq 服务里的 S3 关闭,仅开启 web 和 streaming 服务的 S3,就可以让来自其他服务器的缓存下载在 sidekiq 所在的服务器上,仅自身服务的媒体文件存在 S3 中。
清理其他服务器的旧数据
从数据库中删除未被引用的嘟文,例如来自中继的或来自本地用户不再关注的用户的嘟文,同时没有被回复的或以其他方式与之互动的:docker-compose exec -d sidekiq tootctl statuses remove --days 7
移除本地缓存的其它实例媒体附件:docker-compose exec -d sidekiq tootctl media remove --days 7