Mastodon 是一個基於 ActivityPub 協議的自由、開源社交網路伺服器,使用者可以關注朋友並發現新的朋友。在 Mastodon 上,使用者可以發布任何內容,包括連結、圖片、文字和視頻等。所有 Mastodon 伺服器都可以互相通信,形成一個聯合網路,即使使用實現了 ActivityPub 協議的非 Mastodon 軟體,也可以與 Mastodon 使用者無縫交流!
Mastodon 是一個去中心化的社交網路,這意味著每個使用者可以選擇自己的伺服器(或 “實例”)並控制自己的數據,同時仍然成為 Mastodon 使用者的一部分。由於 Mastodon 基於 ActivityPub 協議,它還可以與使用相同協議的其他去中心化社交網路進行通信,例如 Pleroma、Friendica 和 Hubzilla 等。這種互操作性有助於促進更多樣化和彈性的在線社區,使使用者不會被限制在單個集中式平台或公司中。
下面簡單介紹在一台 VPS 上搭建 Mastodon 的方式(推薦至少 1C2G,基於 Debian 11 root 使用者):
1/ 安裝 Docker 及 Compose#
一條命令:
curl -L get.docker.com | bash
2/ 安裝 Nginx 及 ACME.SH#
這裡推薦由 n.wtf 打包的 Nginx:
# Install required software
apt install -y lsb-release ca-certificates apt-transport-https curl gnupg dpkg
# Download PGP Key
curl -sS https://n.wtf/public.key | gpg --dearmor > /usr/share/keyrings/n.wtf.gpg
# Add repo
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/n.wtf.gpg] https://mirror-cdn.xtom.com/sb/nginx/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/n.wtf.list
# Update system
apt update
# Install Latest Nginx
apt install nginx-extras -y
安裝 acme.sh,一條命令:
curl -L get.acme.sh | bash
安裝完成後,您可能需要關閉當前終端並重新打開它,以使 acme.sh 別名生效。
3/ 安裝 Mastodon#
新建文件夾
mkdir -p /var/www/mastodon && cd /var/www/mastodon
編輯 docker-compose.yml
vim docker-compose.yml
按 i
開始編輯,按 Shift+Ins 粘貼,按 Esc 輸入 :wq
保存退出
version: '3'
services:
db:
restart: always
image: postgres:12.5-alpine
shm_size: 256mb
networks:
- internal_network
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
volumes:
- ./postgres:/var/lib/postgresql/data
redis:
restart: always
image: redis:6-alpine
networks:
- internal_network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
volumes:
- ./redis:/data
# es:
# image: kubesphere/elasticsearch-oss:6.7.0-1-arm64
# environment:
# - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
# - "cluster.name=es-mastodon"
# - "discovery.type=single-node"
# - "bootstrap.memory_lock=true"
# networks:
# - internal_network
# healthcheck:
# test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"]
# volumes:
# - ./elasticsearch:/usr/share/elasticsearch/data
# ulimits:
# memlock:
# soft: -1
# hard: -1
# restart: unless-stopped
web:
image: plusminusio/mastodon:latest-arm64
restart: always
env_file: .env.production
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
networks:
- external_network
- internal_network
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:3000/health || exit 1"]
ports:
- "127.0.0.1:3000:3000"
depends_on:
- db
- redis
# - es
volumes:
- ./public/system:/mastodon/public/system
streaming:
image: plusminusio/mastodon:latest-arm64
restart: always
env_file: .env.production
command: node ./streaming
networks:
- external_network
- internal_network
healthcheck:
test: ["CMD-SHELL", "wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1"]
ports:
- "127.0.0.1:4000:4000"
depends_on:
- db
- redis
sidekiq:
image: plusminusio/mastodon:latest-arm64
restart: always
env_file: .env.production
command: bundle exec sidekiq
depends_on:
- db
- redis
networks:
- external_network
- internal_network
volumes:
- ./public/system:/mastodon/public/system
networks:
external_network:
internal_network:
internal: true
配置數據庫
docker run --name postgres12 -v /var/www/mastodon/postgres:/var/lib/postgresql/data -e POSTGRES_PASSWORD=設置數據庫管理員密碼 --rm -d postgres:12.5-alpine
檢查 postgres 文件夾,應該出現 postgres 相關的多個文件,不是空文件夾。
然後執行
docker exec -it postgres12 psql -U postgres
輸入
CREATE USER mastodon WITH PASSWORD '數據庫密碼(最好和數據庫管理員密碼不一樣)' CREATEDB;
創建 mastodon 使用者,然後停止 docker
docker stop postgres12
配置 .env.production
# 回到 mastodon 文件夾
cd /var/www/mastodon
# 生成文件
touch .env.production
# 配置文件
docker compose run --rm web bundle exec rake mastodon:setup
- 輸入域名
- Enable single user mode? 否
- Using Docker to run Mastodon? 是
- postsql 使用者名稱、數據庫名稱填 mastodon ,密碼部分填剛剛設置的數據庫密碼
- redis 部分都直接回車
- Store uploaded files on the cloud? 這個可填否,如有需要可配置 S3。
- Send e-mails from localhost? 否。然後填入郵件服務設置,推薦使用 Mailazy,具體配置可參照下方。
- This configuration will be written to .env.production Save configuration? 是
- 然後會出現 .env.production 配置,複製下來,先存到電腦裡,等會用。
- 然後會要你建立數據庫和編譯,都選是。最後建立管理員帳號。
成功之後,編輯 .env.production
文件,按 i
開始編輯,按 Shift+Ins 粘貼,按 Esc 輸入 :wq
保存退出
vim .env.production
S3 及 SMTP 信息大致如下
S3_ENABLED=true
S3_PROTOCOL=https
S3_REGION=fr-par
S3_ENDPOINT=https://s3.fr-par.scw.cloud
S3_HOSTNAME=[hidden].s3.fr-par.scw.cloud
S3_BUCKET=[hidden]
AWS_ACCESS_KEY_ID=[hidden]
AWS_SECRET_ACCESS_KEY=[hidden]
S3_ALIAS_HOST=[hidden]
SMTP_SERVER=smtp.mailazy.com
SMTP_PORT=587
SMTP_LOGIN=[hidden]
SMTP_PASSWORD=[hidden]
SMTP_AUTH_METHOD=plain # 該配置僅代表可用於 mailazy,若為其他服務商請做相應更改
SMTP_OPENSSL_VERIFY_MODE=none # 該配置僅代表可用於 mailazy,若為其他服務商請做相應更改
SMTP_FROM_ADDRESS=mastodon@[hidden]
運行
docker compose up -d
為相應文件夾賦權
chown 991:991 -R ./public
chown -R 70:70 ./postgres
# 關閉
docker compose down
# 再次啟動
docker compose up -d
查看運行詳情
docker compose ps
NAME COMMAND SERVICE STATUS PORTS
mastodon-db-1 "docker-entrypoint.s…" db running (healthy)
mastodon-redis-1 "docker-entrypoint.s…" redis running (healthy)
mastodon-sidekiq-1 "/usr/bin/tini -- bu…" sidekiq running 4000/tcp
mastodon-streaming-1 "/usr/bin/tini -- no…" streaming running (healthy) 127.0.0.1:4000->4000/tcp
mastodon-web-1 "/usr/bin/tini -- ba…" web running (healthy) 127.0.0.1:3000->3000/tcp
# 當狀態均為 healthy 的時候即代表成功運行
4/ 配置 Nginx 及 SSL#
創建配置文件
vim /etc/nginx/conf.d/mastodon.conf
複製下方 http 配置信息以申請 SSL 證書,按 i
開始編輯,按 Shift+Ins 粘貼,按 Esc 輸入 :wq
保存退出
server {
listen 80;
# 若配置了 IPV6,刪除下方的井號
# listen [::]:80;
server_name mastodon.im.sb;
root /var/www/mastodon/public;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
# 將 mastodon.im.sb 替換成您自己的域名
重載 Nginx
nginx -t
# 確保配置文件無異常
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重載
nginx -s reload
申請 SSL 證書
將您的域名 A 記錄及 AAAA 記錄(若有)指向 VPS IP,然後申請域名證書
acme.sh --issue -d mastodon.im.sb -w /var/www/mastodon/public --server letsencrypt
# 將 mastodon.im.sb 替換成您自己的域名
申請成功後,我們需要其中的:
# SSL 完整證書
/root/.acme.sh/mastodon.im.sb_ecc/fullchain.cer
# SSL 私鑰
/root/.acme.sh/mastodon.im.sb_ecc/mastodon.im.sb.key
再次編輯配置文件
vim /etc/nginx/conf.d/mastodon.conf
複製下方完整配置信息,按 i
開始編輯,按 Shift+Ins 粘貼,按 Esc 輸入 :wq
保存退出
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream backend {
server 127.0.0.1:3000 fail_timeout=0;
}
upstream streaming {
server 127.0.0.1:4000 fail_timeout=0;
}
server {
listen 80;
# 若配置了 IPV6,刪除下方的井號
# listen [::]:80;
server_name mastodon.im.sb;
root /var/www/mastodon/public;
location /.well-known/acme-challenge/ { allow all; }
location / { return 301 https://$host$request_uri; }
}
server {
listen 443 ssl http2;
# 若配置了 IPV6,刪除下方的井號
# listen [::]:443 ssl http2;
server_name mastodon.im.sb;
ssl_certificate /root/.acme.sh/mastodon.im.sb_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/mastodon.im.sb_ecc/mastodon.im.sb.key;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers off;
ssl_ecdh_curve X25519:secp384r1;
ssl_session_cache shared:MASTODON:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 119.29.29.29 valid=300s;
resolver_timeout 5s;
root /var/www/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;
keepalive_timeout 70;
sendfile on;
client_max_body_size 80m;
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;
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 403 404 500 501 502 503 504 /500.html;
}
# 將 mastodon.im.sb 替換成您自己的域名
重載 Nginx
nginx -t
# 確保配置文件無異常
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重載
nginx -s reload
現在訪問您的域名即可訪問 Mastodon。
5/ 設置管理員#
訪問您的 Mastodon 並註冊一個帳號,返回終端運行:
# 回到 mastodon 文件夾
cd /var/www/mastodon
docker compose run --rm web bin/tootctl accounts modify [YOURACCOUNT] --role Owner
或者直接在終端創建一個管理員帳號:
docker compose run --rm web bin/tootctl accounts create [YOURACCOUNT] --email [[email protected]] --confirmed --role Owner
將在終端中顯示一個隨機生成的密碼。
👉 部分內容參考了此篇文章。