Unraid 搭建 mastodon 个人微博平台
此篇文章只是做介绍,照抄我估计是无法完成搭建的,有很多部署的坑在里面,我没多做介绍,懒得码字,仅供参考。
1. mastodon 是个啥?
github:https://github.com/mastodon/mastodon
自托管,可以多用户互联通信的微博社区。
Mastodon 是一个基于 ActivityPub 的免费开源社交网络服务器,用户可以在其中关注朋友并发现新朋友。在 Mastodon 上,用户可以发布他们想要的任何内容:链接、图片、文本、视频。所有 Mastodon 服务器都可以作为联合网络进行互操作(一台服务器上的用户可以与另一台服务器上的用户无缝通信,包括实现 ActivityPub 的非 Mastodon 软件)!
有 web、Android、ios、windows/mac/linux桌面各种平台的客户端,https://joinmastodon.org/apps
2. 我为什么要用mastodon?
1. 想要有以时间轴为顺序的文字记录,按照时间线更新,记录我的想法、文章、日志、随笔、乱想等,然后可以按时间查找,也可以全文搜索,然后评论我之前写过的文字,有点像自言自语了,哈哈。
2. 像微博一样,可以和家人或者好友针对某些随笔做留言和讨论的记录,只有自己人才能看得到,不想共享在网络上。
3. 需要注意的点
请使用https,http的访问也会有异常,不要问为啥,
只能用80和443访问,不能使用其他端口,否则有异常,已经体验过,我自己用的一台腾讯云主机反代到home ddns才注册使用
我目前的方案是,unraid安装docker nginx 用的是80和443端口,然后防火墙映射为801和4431,再由云主机反代到 4431上面
4. 安装
4.1 unraid安装docker-compose参考
https://post.smzdm.com/p/a0dn3xlr/
📢:我这边用的是unraid插件的docker-compose,可以在web页面修改配置文件,如果你不想这么用,就自己看着办,不用跟着我的文件路径来。
4.2 web页面编辑 docker-compose.yml 配置
version: '3'
services:
db:
restart: always
image: postgres:14-alpine
shm_size: 256mb
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
ports:
- "54132:5432"
networks:
- mastodon_networks
volumes:
- /mnt/user/appdata/mastodon/postgres14:/var/lib/postgresql/data
environment:
- "POSTGRES_HOST_AUTH_METHOD=trust"
- "POSTGRES_DB=mastodon"
- "POSTGRES_USER=mastodon"
- "POSTGRES_PASSWORD=mastodon"
redis:
restart: always
image: redis:6-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
ports:
- "26379:6379"
networks:
- mastodon_networks
volumes:
- /mnt/user/appdata/mastodon/redis:/data
es:
restart: always
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
environment:
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- "cluster.name=es-mastodon"
- "discovery.type=single-node"
- "bootstrap.memory_lock=true"
healthcheck:
test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
ports:
- "9200:9200"
- "9201:9201"
networks:
- mastodon_networks
volumes:
- /mnt/user/appdata/mastodon/elasticsearch:/usr/share/elasticsearch/data
ulimits:
memlock:
soft: -1
hard: -1
web:
image: tootsuite/mastodon
restart: always
env_file: .env
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3001"
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"]
ports:
- "3001:3001"
networks:
- mastodon_networks
depends_on:
- db
- redis
- es
volumes:
- /mnt/user/appdata/mastodon/public/system:/mastodon/public/system
streaming:
image: tootsuite/mastodon
restart: always
env_file: .env
command: node ./streaming
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1"]
ports:
- "4000:4000"
networks:
- mastodon_networks
depends_on:
- db
- redis
sidekiq:
image: tootsuite/mastodon
restart: always
env_file: .env
command: bundle exec sidekiq
depends_on:
- db
- redis
networks:
- mastodon_networks
volumes:
- /mnt/user/appdata/mastodon/public/system:/mastodon/public/system
healthcheck:
test: ["CMD-SHELL", "ps aux | grep '[s]idekiq 6' || false"]
## Uncomment to enable federation with tor instances along with adding the following ENV variables
## http_proxy=http://privoxy:8118
## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true
# tor:
# image: sirboops/tor
# networks:
# - mastodon_networks
#
# privoxy:
# image: sirboops/privoxy
# volumes:
# - ./priv-config:/opt/config
# networks:
# - mastodon_networks
networks:
mastodon_networks:
external: true
4.3 打开unraid终端配置
进到 /boot/config/plugins/compose.manager/projects/mastodon 路径, 然后执行命令 docker-compose -f compose.yml run --rm web bundle exec rake mastodon:setup 进行初始化配置
源码安装参考:https://docs.joinmastodon.org/admin/install/
root@UncleZhao:/boot/config/plugins/compose.manager/projects/mastodon# docker-compose -f compose.yml run --rm web bundle exec rake mastodon:setup
[+] Running 3/3
⠿ Container mastodon_redis_1 Created 0.2s
⠿ Container mastodon_db_1 Created 0.2s
⠿ Container mastodon_es_1 Created 0.2s
[+] Running 3/3
⠿ Container mastodon_db_1 Started 0.5s
⠿ Container mastodon_redis_1 Started 0.5s
⠿ Container mastodon_es_1 Started 0.6s
/opt/ruby/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError
/opt/mastodon/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.0/lib/net/protocol.rb:66: warning: previous definition of ProtocRetryError was here
/opt/ruby/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE
/opt/mastodon/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.0/lib/net/protocol.rb:206: warning: previous definition of BUFSIZE was here
/opt/ruby/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket
/opt/mastodon/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.0/lib/net/protocol.rb:503: warning: previous definition of Socket was here
Your instance is identified by its domain name. Changing it afterward will break things.
Domain name: mastodon.testonetest.com ###最终访问的反代域名
Single user mode disables registrations and redirects the landing page to your public profile.
Do you want to enable single user mode? yes ### 不能注册
Are you using Docker to run Mastodon? Yes ### docker-compose安装的,可以去掉ip地址链接数据库的配置,可以用cnmae
PostgreSQL host: db
PostgreSQL port: 5432
Name of PostgreSQL database: mastodon ### yml 文件 postgres上面的变量
Name of PostgreSQL user: mastodon ### yml 文件 postgres上面的变量
Password of PostgreSQL user: ### yml 文件 postgres上面的变量
Database configuration works! 🎆 ### 这里会进行链接测试,如果👆🏻的配置有问题,这里会失败,然后让你重新输入
Redis host: redis
Redis port: 6379
Redis password:
Redis configuration works! 🎆
Do you want to store uploaded files on the cloud? No
Do you want to send e-mails from localhost? No
SMTP server: smtp.mailgun.org
SMTP port: 587
SMTP username:
SMTP password:
SMTP authentication: plain
SMTP OpenSSL verify mode: none
E-mail address to send e-mails "from": Mastodon <notifications@mastodon.testonetest.com>
Send a test e-mail with this configuration right now? no
This configuration will be written to .env.production
Save configuration? Yes
Below is your configuration, save it to an .env.production file outside Docker:
# Generated with mastodon:setup on 2022-02-14 07:07:41 UTC
# Some variables in this file will be interpreted differently whether you are
# using docker-compose or not.
LOCAL_DOMAIN=mastodon.testonetest.com
SINGLE_USER_MODE=true
SECRET_KEY_BASE=85116394a12341245aser235rac36cd85626244f8a04c3198a8e82er235rac36cd856er235rac36cd8563d56d2ce90bb2
OTP_SECRET=88bf74f27dd182f397798626d68a34ea19eer235rac36cd856d1234124bb9a2fb74527d85626244f8a04c3199e62218c4964e73
VAPID_PRIVATE_KEY=ev8zOgnxva1I512er235rac36cd8564sdf137Xggn5oQE=
VAPID_PUBLIC_KEY=BG8hS124sdf1234aer235rac36cd856sdfbggM-ycS5YPM=
DB_HOST=db
DB_PORT=5432
DB_NAME=mastodon
DB_USER=mastodon
DB_PASS=mastodon
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
SMTP_SERVER=smtp.mailgun.org
SMTP_PORT=587
SMTP_LOGIN=
SMTP_PASSWORD=
SMTP_AUTH_METHOD=plain
SMTP_OPENSSL_VERIFY_MODE=none
SMTP_FROM_ADDRESS=Mastodon <notifications@mastodon.testonetest.com>
It is also saved within this container so you can proceed with this wizard.
Now that configuration is saved, the database schema must be loaded.
If the database already exists, this will erase its contents.
Prepare the database now? Yes
Running `RAILS_ENV=production rails db:setup` ...
/opt/ruby/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError
/opt/mastodon/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.0/lib/net/protocol.rb:66: warning: previous definition of ProtocRetryError was here
/opt/ruby/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE
/opt/mastodon/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.0/lib/net/protocol.rb:206: warning: previous definition of BUFSIZE was here
/opt/ruby/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket
/opt/mastodon/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.1.0/lib/net/protocol.rb:503: warning: previous definition of Socket was here
Database 'mastodon' already exists
[strong_migrations] DANGER: No lock timeout set
Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)
Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)
Switching object-storage-safely from green to red because Redis::CannotConnectError Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)
Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)
Done!
All done! You can now power on the Mastodon server 🐘
Do you want to create an admin user straight away? Yes
Username: admin
E-mail: admin@admin.com
Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED) ### 可以无需理会这个报错,把配置加到env文件后就不会有这个问题了
Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)
Switching object-storage-safely from green to red because Redis::CannotConnectError Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)
Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)
You can login with the password: 12er235rac36cd8564sdf137Xggn5
You can change your password once you login.
4.4 将配置好的env 环境变量参数添加到.env文件进去,然后启动
# Generated with mastodon:setup on 2022-02-14 07:07:41 UTC
# Some variables in this file will be interpreted differently whether you are
# using docker-compose or not.
LOCAL_DOMAIN=mastodon.testonetest.com
SINGLE_USER_MODE=true
SECRET_KEY_BASE=85116394a12341245aser235rac36cd85626244f8a04c3198a8e82er235rac36cd856er235rac36cd8563d56d2ce90bb2
OTP_SECRET=88bf74f27dd182f397798626d68a34ea19eer235rac36cd856d1234124bb9a2fb74527d85626244f8a04c3199e62218c4964e73
VAPID_PRIVATE_KEY=ev8zOgnxva1I512er235rac36cd8564sdf137Xggn5oQE=
VAPID_PUBLIC_KEY=BG8hS124sdf1234aer235rac36cd856sdfbggM-ycS5YPM=
DB_HOST=db
DB_PORT=5432
DB_NAME=mastodon
DB_USER=mastodon
DB_PASS=mastodon
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
SMTP_SERVER=smtp.mailgun.org
SMTP_PORT=587
SMTP_LOGIN=
SMTP_PASSWORD=
SMTP_AUTH_METHOD=plain
SMTP_OPENSSL_VERIFY_MODE=none
SMTP_FROM_ADDRESS="Mastodon <notifications@mastodon.testonetest.com>"
ES_ENABLED=true
ES_HOST=es
ES_PORT=9200
4.5 nginx 反代配置,官网例子
https://github.com/mastodon/mastodon/blob/main/dist/nginx.conf
我的 nginx 配置
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream backend {
server 192.168.31.130:3001 fail_timeout=0;
}
upstream streaming {
server 192.168.31.130:4000 fail_timeout=0;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
server {
listen 80;
listen [::]:80;
listen 801;
listen [::]:801;
server_name mastodon.unclezhao.top;
root /mnt/user/appdata/mastodon/public;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
listen 4431 ssl http2;
listen [::]:4431 ssl http2;
server_name mastodon.unclezhao.top;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Uncomment these lines once you acquire a certificate:
ssl_certificate /config/nginx/ssl/npm-2/cert.pem;
ssl_certificate_key /config/nginx/ssl/npm-2/privkey.pem;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
root /mnt/user/appdata/mastodon/public;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
try_files $uri @proxy;
}
location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri @proxy;
}
location /sw.js {
add_header Cache-Control "public, max-age=0";
add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri @proxy;
}
location @proxy {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_pass http://backend;
proxy_buffering on;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache CACHE;
proxy_cache_valid 200 7d;
proxy_cache_valid 410 24h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cached $upstream_cache_status;
add_header Strict-Transport-Security "max-age=31536000" always;
tcp_nodelay on;
}
location /api/v1/streaming {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Proxy "";
proxy_pass http://streaming;
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
error_page 500 501 502 503 504 /500.html;
}
4.6 云主机反代到 homelab 的域名上面完成(留作参考,请忽略)
📢 :至于我为啥要这么搞,是因为我需要外网访问,家庭环境又不能使用80和443外网映射,只能做两层反代,或者你们可以走vpn的方式来处理这个问题。
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;
server {
listen 80;
listen [::]:80;
server_name mastodon.testonetest.com;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mastodon.testonetest.com;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# Uncomment these lines once you acquire a certificate:
ssl_certificate ssl/testonetest.com/cert.pem;
ssl_certificate_key ssl/testonetest.com/key.pem;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
try_files $uri @proxy;
}
location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri @proxy;
}
location /sw.js {
add_header Cache-Control "public, max-age=0";
add_header Strict-Transport-Security "max-age=31536000" always;
try_files $uri @proxy;
}
location @proxy {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Proxy "";
proxy_pass_header Server;
proxy_pass https://mastodon.homeproxy.top:431;
proxy_buffering on;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache CACHE;
proxy_cache_valid 200 7d;
proxy_cache_valid 410 24h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cached $upstream_cache_status;
add_header Strict-Transport-Security "max-age=31536000" always;
tcp_nodelay on;
}
location /api/v1/streaming {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Proxy "";
<!-- proxy_pass https://mastodon.homeproxy.top:431; -->
proxy_buffering off;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
tcp_nodelay on;
}
error_page 500 501 502 503 504 /500.html;
}
主要改 反代位置,去掉upstream backend 和 upstream streaming 就好了
5. 安装完成展示
6. 参考文章








ilray
校验提示文案
itonas
校验提示文案
宫保鸡丁盖浇饭
校验提示文案
ccfer
校验提示文案
蒟蒻白
校验提示文案
蒟蒻白
校验提示文案
ccfer
校验提示文案
宫保鸡丁盖浇饭
校验提示文案
itonas
校验提示文案
ilray
校验提示文案