YJK

独立世界

Independent World
twitter
telegram

搭建 Mastodon,加入聯邦社交網絡

Mastodon 是一個基於 ActivityPub 協議的自由、開源社交網路伺服器,使用者可以關注朋友並發現新的朋友。在 Mastodon 上,使用者可以發布任何內容,包括連結、圖片、文字和視頻等。所有 Mastodon 伺服器都可以互相通信,形成一個聯合網路,即使使用實現了 ActivityPub 協議的非 Mastodon 軟體,也可以與 Mastodon 使用者無縫交流!

Mastodon 是一個去中心化的社交網路,這意味著每個使用者可以選擇自己的伺服器(或 “實例”)並控制自己的數據,同時仍然成為 Mastodon 使用者的一部分。由於 Mastodon 基於 ActivityPub 協議,它還可以與使用相同協議的其他去中心化社交網路進行通信,例如 Pleroma、Friendica 和 Hubzilla 等。這種互操作性有助於促進更多樣化和彈性的在線社區,使使用者不會被限制在單個集中式平台或公司中。

下面簡單介紹在一台 VPS 上搭建 Mastodon 的方式(推薦至少 1C2G,基於 Debian 11 root 使用者):

image

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
  1. 輸入域名
  2. Enable single user mode? 否
  3. Using Docker to run Mastodon? 是
  4. postsql 使用者名稱、數據庫名稱填 mastodon ,密碼部分填剛剛設置的數據庫密碼
  5. redis 部分都直接回車
  6. Store uploaded files on the cloud? 這個可填否,如有需要可配置 S3。
  7. Send e-mails from localhost? 否。然後填入郵件服務設置,推薦使用 Mailazy具體配置可參照下方
  8. This configuration will be written to .env.production Save configuration? 是
  9. 然後會出現 .env.production 配置,複製下來,先存到電腦裡,等會用
  10. 然後會要你建立數據庫和編譯,都選是。最後建立管理員帳號。

成功之後,編輯 .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

將在終端中顯示一個隨機生成的密碼。


👉 部分內容參考了此篇文章

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。