如何在 Debian 12 上安装 Mastodon 社交网络如何在 Debian 12 上安装 Mastodon 社交网络如何在 Debian 12 上安装 Mastodon 社交网络如何在 Debian 12 上安装 Mastodon 社交网络
  • 业务
  • 目标
  • 支持
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容

如何在 Debian 12 上安装 Mastodon 社交网络

发表 admin at 2025年2月28日
类别
  • 未分类
标签
月額480円〜の高速レンタルサーバー ColorfulBox

Mastodon 是一个免费、去中心化、开源的社交网络。它是作为 Twitter 的替代品而创建的。就像 Twitter 一样,人们可以互相关注、发布消息、图像和视频。但与 Twitter 不同的是,它的内容没有中央存储或权威机构。

相反,Mastodon 在数千个不同的服务器上运行,每个服务器都由社区的不同成员运行。在一台服务器上注册的用户可以轻松连接到另一网络上的用户,并跨实例相互关注。

任何人都可以安装他们的 Mastodon 服务器实例。本教程将教您如何使用 Docker 在 Debian 12 的服务器上设置 Mastodon 实例。 Docker 通过包含容器中所需的所有包和服务,使安装 Mastodon 变得容易。

先决条件

    运行 Debian 12 且至少具有 2 个 CPU 核心和 2GB 内存的服务器。您将需要根据要求升级服务器。

    具有 sudo 权限的非 root 用户。

    指向您的服务器的完全限定域名 (FQDN)。出于我们的目的,我们将使用 mastodon.example.com 作为域名。

    Mastodon 向用户发送电子邮件通知。我们建议您使用第 3 方事务性邮件服务,例如 Mailgun、SendGrid、Amazon SES 或 Sparkpost。本指南中的说明将使用 Amazon SES。

    确保一切都已更新。

    $ sudo apt update
    

    安装基本实用程序包。其中一些可能已经安装。

    $ sudo apt install curl wget nano software-properties-common dirmngr apt-transport-https ca-certificates lsb-release debian-archive-keyring gnupg2 ufw unzip -y
    

第 1 步 - 配置防火墙

第一步是配置防火墙。 Debian 默认带有 ufw(简单防火墙)。

检查防火墙是否正在运行。

$ sudo ufw status

您应该得到以下输出。

Status: inactive

允许 SSH 端口,以便防火墙在启用它时不会中断当前连接。

$ sudo ufw allow OpenSSH

还允许 HTTP 和 HTTPS 端口。

$ sudo ufw allow http
$ sudo ufw allow https

启用防火墙

$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

再次检查防火墙的状态。

$ sudo ufw status

您应该看到类似的输出。

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

第 2 步 - 安装 Docker 和 Docker Compose

Debian 12 附带旧版本的 Docker。要安装最新版本,首先导入 Docker GPG 密钥。

$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg

创建 Docker 存储库文件。

$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

更新系统存储库列表。

$ sudo apt update

安装最新版本的 Docker。

$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

验证它是否正在运行。

$ sudo systemctl status docker
? docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Mon 2024-01-01 09:00:14 UTC; 17s ago
TriggeredBy: ? docker.socket
       Docs: https://docs.docker.com
   Main PID: 1839 (dockerd)
      Tasks: 9
     Memory: 27.6M
        CPU: 598ms
     CGroup: /system.slice/docker.service
             ??1839 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

默认情况下,Docker 需要 root 权限。如果您想避免每次运行 docker 命令时都使用 sudo,请将您的用户名添加到 docker 组中。

$ sudo usermod -aG docker $(whoami)

您需要注销服务器并以同一用户身份重新登录才能启用此更改或使用以下命令。

$ su - ${USER}

确认您的用户已添加到 Docker 组。

$ groups
navjot sudo users docker

第 3 步 - 准备安装

Elasticsearch 的 mmap 计数的默认限制非常低。运行以下命令检查默认值。

$ sudo sysctl vm.max_map_count

您将得到以下输出。

vm.max_map_count = 65530

使用以下命令增加该值。

$ echo "vm.max_map_count=262144" | sudo tee /etc/sysctl.d/90-max_map_count.conf
vm.max_map_count=262144
$ sudo sysctl --load /etc/sysctl.d/90-max_map_count.conf
vm.max_map_count=262144

第 4 步 - 安装 Mastodon

创建目录并设置所有权

为 Mastodon 和相关服务创建目录。

$ sudo mkdir -p /opt/mastodon/database/{postgresql,pgbackups,redis,elasticsearch}
$ sudo mkdir -p /opt/mastodon/web/{public,system}
$ sudo mkdir -p /opt/mastodon/branding

为 Elasticsearch、Web 和备份目录设置正确的所有权。

$ sudo chown 991:991 /opt/mastodon/web/{public,system}
$ sudo chown 1000 /opt/mastodon/database/elasticsearch
$ sudo chown 70:70 /opt/mastodon/database/pgbackups

切换到 Mastodon 目录。

$ cd /opt/mastodon

创建环境和docker compose文件

为应用程序和数据库创建环境文件。

$ sudo touch application.env database.env

创建并打开 Docker compose 文件进行编辑。

$ sudo nano docker-compose.yml

将以下代码粘贴到其中。

services:
  postgresql:
    image: postgres:16-alpine
    env_file: database.env
    restart: always
    shm_size: 512mb
    healthcheck:
      test: ['CMD', 'pg_isready', '-U', 'postgres']
    volumes:
      - postgresql:/var/lib/postgresql/data
      - pgbackups:/backups
    networks:
      - internal_network

  redis:
    image: redis:7-alpine
    restart: always
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
    volumes:
      - redis:/data
    networks:
      - internal_network

  redis-volatile:
    image: redis:7-alpine
    restart: always
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
    networks:
      - internal_network

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.17.16
    restart: always
    env_file: database.env
    environment:
      - cluster.name=elasticsearch-mastodon
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - xpack.security.enabled=true
      - ingest.geoip.downloader.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true"
      - xpack.license.self_generated.type=basic
      - xpack.watcher.enabled=false
      - xpack.graph.enabled=false
      - xpack.ml.enabled=false
      - thread_pool.write.queue_size=1000
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    healthcheck:
      test: ["CMD-SHELL", "nc -z elasticsearch 9200"]
    volumes:
      - elasticsearch:/usr/share/elasticsearch/data
    networks:
      - internal_network
    ports:
      - '127.0.0.1:9200:9200'

  website:
    image: tootsuite/mastodon:v4.2.3
    env_file:
      - application.env
      - database.env
    command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
    restart: always
    depends_on:
      - postgresql
      - redis
      - redis-volatile
      - elasticsearch
    ports:
      - '127.0.0.1:3000:3000'
    networks:
      - internal_network
      - external_network
    healthcheck:
      test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1']
    volumes:
      - uploads:/mastodon/public/system

  shell:
    image: tootsuite/mastodon:v4.2.3
    env_file:
      - application.env
      - database.env
    command: /bin/bash
    restart: "no"
    networks:
      - internal_network
      - external_network
    volumes:
      - uploads:/mastodon/public/system
      - static:/static

  streaming:
    image: tootsuite/mastodon:v4.2.3
    env_file:
      - application.env
      - database.env
    command: node ./streaming
    restart: always
    depends_on:
      - postgresql
      - redis
      - redis-volatile
      - elasticsearch
    ports:
      - '127.0.0.1:4000:4000'
    networks:
      - internal_network
      - external_network
    healthcheck:
      test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1']

  sidekiq:
    image: tootsuite/mastodon:v4.2.3
    env_file:
      - application.env
      - database.env
    command: bundle exec sidekiq
    restart: always
    depends_on:
      - postgresql
      - redis
      - redis-volatile
      - website
    networks:
      - internal_network
      - external_network
    healthcheck:
      test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"]
    volumes:
      - uploads:/mastodon/public/system

networks:
  external_network:
  internal_network:
    internal: true

volumes:
  postgresql:
    driver_opts:
      type: none
      device: /opt/mastodon/database/postgresql
      o: bind
  pgbackups:
    driver_opts:
      type: none
      device: /opt/mastodon/database/pgbackups
      o: bind
  redis:
    driver_opts:
      type: none
      device: /opt/mastodon/database/redis
      o: bind
  elasticsearch:
    driver_opts:
      type: none
      device: /opt/mastodon/database/elasticsearch
      o: bind
  uploads:
    driver_opts:
      type: none
      device: /opt/mastodon/web/system
      o: bind
  static:
    driver_opts:
      type: none
      device: /opt/mastodon/web/public
      o: bind

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

在撰写本教程时,Mastodon 的最新可用版本是 v4.2.3。检查 Mastodon GitHub Releases 页面并适当调整 Docker compose 文件中的版本。我们还使用最新版本的 PostgreSQL 和 Redis。您可以根据您的要求调整它们。我们目前使用的是 Elasticsearch 7.17.16。

创建应用程序机密

下一步是创建应用程序机密值。

通过运行以下命令两次来生成 SECRET_KEY_BASE 和 OTP_SECRET 值。第一次将需要一些时间,因为它会拉取图像。

$ docker compose run --rm shell bundle exec rake secret
349623c049e3b856f6848638146e459857862b908ed387bbef372a30d9bd7c604fc4de5338addc86bd369a99d38ef59bacfa28e02a1750f7094ea6ede05457b8

您还可以使用 openssl 实用程序来实现相同的目的。

$ openssl rand -hex 64
ae01cf7d4dfae0182461a1345f1f2bf159658a27339ffafe7d356bef9ee8d4fa015ab2e72a608f236bd8e3f9b2af2dcb1d55ee5c8e43646959112c7da5582f4b

使用以下命令生成 VAPID_PRIVATE_KEY 和 VAPID_PUBLIC_KEY 值。

$ docker compose run --rm shell bundle exec rake mastodon:webpush:generate_vapid_key

您将得到类似的输出。

VAPID_PRIVATE_KEY=u2qsCs5JdmdmMLnUuU0sgmFGvZedteJz-lFB_xF4_ac=
VAPID_PUBLIC_KEY=BJXjE2hIXvFpo6dnHqyf1i-2PcP-cBoL95UCmhhxwlAgtFw_vnrYp4GBneR7_cmI9LZUYjHFh-TBAPSb9WTqH9A=

使用 openssl 实用程序生成 PostgreSQL 和 Elasticsearch 密码。

$ openssl rand -hex 15
dd0bd7a95960623ed8e084a1fb7d5c
$ openssl rand -hex 15
0fb52834c991b5e296c647166185bc

乳齿象环境文件

打开 application.env 文件进行编辑。

$ sudo nano application.env

将以下行粘贴到其中。

# environment
RAILS_ENV=production
NODE_ENV=production

# domain
LOCAL_DOMAIN=mastodon.example.com

# redirect to the first profile
SINGLE_USER_MODE=false

# do not serve static files
RAILS_SERVE_STATIC_FILES=false

# concurrency
WEB_CONCURRENCY=2
MAX_THREADS=5

# pgbouncer
#PREPARED_STATEMENTS=false

# locale
DEFAULT_LOCALE=en

# email, not used
SMTP_SERVER=email-smtp.us-west-2.amazonaws.com
SMTP_PORT=587
SMTP_LOGIN=AKIA3FIG4NVFB343PZEI
SMTP_PASSWORD=AZX01WiA6JGbeZ2pwVXnyC9DhEa2nKcmXSu/zbLp
[email 

# secrets
SECRET_KEY_BASE=349623c049e3b856f6848638146e459857862b908ed387bbef372a30d9bd7c604fc4de5338addc86bd369a99d38ef59bacfa28e02a1750f7094ea6ede05457b8
OTP_SECRET=ae01cf7d4dfae0182461a1345f1f2bf159658a27339ffafe7d356bef9ee8d4fa015ab2e72a608f236bd8e3f9b2af2dcb1d55ee5c8e43646959112c7da5582f4b

# Changing VAPID keys will break push notifications
VAPID_PRIVATE_KEY=oNe_4BEL7Tpc3iV8eMtLegfLwrzA7ifitGJ2YOg3dUM=
VAPID_PUBLIC_KEY=BKBgmB90vIrJg6Ifq3cCHixalyPghJDkui9vm1wscxvAfNNoAQL0KinoxRTLDp0UFlGK_ahUG2n4W2n4x9AUAWM=

# IP and session retention
# -----------------------
# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml
# to be less than daily if you lower IP_RETENTION_PERIOD below two days (172800).
# -----------------------
IP_RETENTION_PERIOD=2592000
SESSION_RETENTION_PERIOD=2592000

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

我们已启用 Amazon SES 邮件服务。如果不需要,可以删除该部分。默认情况下,Mastodon 保留 IP 地址 1 年,但我们已将其更改为 30 天(2592000 秒)。您可以根据您的要求更改它。确保保存超过 2 天,否则,您将需要进行更多修改,这超出了我们教程的范围。

打开database.env 文件进行编辑。

$ sudo nano database.env

将以下行粘贴到其中。

# postgresql configuration
POSTGRES_USER=mastodon
POSTGRES_DB=mastodon
POSTGRES_PASSWORD=0fb52834c991b5e296c647166185bc
PGPASSWORD=0fb52834c991b5e296c647166185bc
PGPORT=5432
PGHOST=postgresql
PGUSER=mastodon

# pgbouncer configuration
#POOL_MODE=transaction
#ADMIN_USERS=postgres,mastodon
#DATABASE_URL="postgres://mastodon:0fb52834c991b5e296c647166185bc@postgresql:5432/mastodon"

# elasticsearch
ELASTIC_PASSWORD=dd0bd7a95960623ed8e084a1fb7d5c

# mastodon database configuration
#DB_HOST=pgbouncer
DB_HOST=postgresql
DB_USER=mastodon
DB_NAME=mastodon
DB_PASS=0fb52834c991b5e296c647166185bc
DB_PORT=5432

REDIS_HOST=redis
REDIS_PORT=6379

CACHE_REDIS_HOST=redis-volatile
CACHE_REDIS_PORT=6379

ES_ENABLED=true
ES_HOST=elasticsearch
ES_PORT=9200
ES_USER=elastic
ES_PASS=dd0bd7a95960623ed8e084a1fb7d5c

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

准备乳齿象

准备好静态文件以供 Nginx 提供服务。这一步需要一些时间,因为 Docker 会第一次拉取所有镜像。

$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"

调出数据层。

$ docker compose up -d postgresql redis redis-volatile

检查容器的状态。

$ watch docker compose ps

等待运行(健康),然后按Ctrl + C并使用以下命令初始化数据库。

$ docker compose run --rm shell bundle exec rake db:setup

如果您收到有关数据库 mastodon 已存在的错误,请运行以下命令。

$ docker compose run --rm shell bundle exec rake db:migrate

第 5 步 - 安装 Nginx

Debian 12 附带旧版本的 Nginx。要安装最新版本,您需要下载官方 Nginx 存储库。

导入 Nginx 的签名密钥。

$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
    | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

添加 Nginx 主线版本的存储库。

$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list

更新系统存储库。

$ sudo apt update

安装 Nginx。

$ sudo apt install nginx

验证安装。在 Debian 系统上,您需要 sudo 来运行以下命令。

$ sudo nginx -v
nginx version: nginx/1.25.3

启动 Nginx 服务器。

$ sudo systemctl start nginx

检查服务器的状态。

$ sudo systemctl status nginx
? nginx.service - nginx - high performance web server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Mon 2024-01-01 10:17:38 UTC; 4s ago
       Docs: https://nginx.org/en/docs/
    Process: 8972 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
   Main PID: 8973 (nginx)
      Tasks: 3 (limit: 4637)
     Memory: 2.9M
        CPU: 17ms
     CGroup: /system.slice/nginx.service
             ??8973 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
             ??8974 "nginx: worker process"
             ??8975 "nginx: worker process"

Jan 01 10:17:38 mastodon systemd[1]: Starting nginx.service - nginx - high performance web server...
Jan 01 10:17:38 mastodon systemd[1]: Started nginx.service - nginx - high performance web server.

第 6 步 - 安装 SSL

我们需要安装 Certbot 来生成 SSL 证书。您可以使用 Debian 的存储库安装 Certbot,也可以使用 Snapd 工具获取最新版本。我们将使用 Snapd 版本。

Debian 12 并未安装 Snapd。安装 Snapd 软件包。

$ sudo apt install snapd

运行以下命令以确保您的 Snapd 版本是最新的。确保您的 Snapd 版本是最新的。

$ sudo snap install core
$ sudo snap refresh core

安装证书机器人。

$ sudo snap install --classic certbot

使用以下命令通过创建指向 /usr/bin 目录的符号链接来确保 Certbot 命令运行。

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

验证安装。

$ certbot --version
certbot 2.8.0

运行以下命令生成 SSL 证书。

$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email  -d mastodon.example.com

上述命令会将证书下载到服务器上的 /etc/letsencrypt/live/mastodon.example.com 目录中。

生成 Diffie-Hellman 组证书。

$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

检查 Certbot 续订调度程序服务。

$ systemctl list-timers

您会发现 snap.certbot.renew.service 是计划运行的服务之一。

NEXT                        LEFT        LAST                        PASSED             UNIT                    ACTIVATES
-----------------------------------------------------------------------------------------------------------------------------------------
Mon 2024-01-01 20:03:52 UTC 9h left     Mon 2023-12-11 21:56:24 UTC 2 weeks 6 days ago apt-daily.timer         apt-daily.service
Mon 2024-01-01 21:06:00 UTC 10h left    -                           -                  snap.certbot.renew.timersnap.certbot.renew.service
Tue 2024-01-02 00:00:00 UTC 13h left    -                           -                  dpkg-db-backup.timer    dpkg-db-backup.service

对该过程进行一次演练,以检查 SSL 续订是否正常工作。

$ sudo certbot renew --dry-run

如果没有看到任何错误,则一切都已准备就绪。您的证书将自动更新。

第 7 步 - 配置 Nginx

打开文件 /etc/nginx/nginx.conf 进行编辑。

$ sudo nano /etc/nginx/nginx.conf

在 include /etc/nginx/conf.d/*.conf; 行之前添加以下行。

server_names_hash_bucket_size 64;

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

创建并打开文件 /etc/nginx/conf.d/mastodon.conf 进行编辑。

$ sudo nano /etc/nginx/conf.d/mastodon.conf

将以下代码粘贴到其中。

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;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;

server {
  listen 80 default_server;
  server_name mastodon.example.com;
  location / { return 301 https://$host$request_uri; }
}

server {
   listen 443 ssl;
   server_name mastodon.example.com;
   
   access_log  /var/log/nginx/mastodon.access.log;
   error_log   /var/log/nginx/mastodon.error.log;

   http2 on; # Enable HTTP/2 - works only on Nginx 1.25.1+

   ssl_certificate /etc/letsencrypt/live/mastodon.example.com/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/mastodon.example.com/privkey.pem;
   ssl_trusted_certificate /etc/letsencrypt/live/mastodon.example.com/chain.pem;
   ssl_session_timeout 1d;

   # Enable TLS versions (TLSv1.3 is required upcoming HTTP/3 QUIC).
   ssl_protocols TLSv1.2 TLSv1.3;

   # Enable TLSv1.3's 0-RTT. Use $ssl_early_data when reverse proxying to
   # prevent replay attacks.
   #
   # @see: https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data
   ssl_early_data on;

   ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384';
   ssl_prefer_server_ciphers on;
   ssl_session_cache shared:SSL:10m;
   ssl_session_tickets off;
   
   keepalive_timeout    70;
   sendfile             on;
   client_max_body_size 80m;

   # OCSP Stapling ---
   # fetch OCSP records from URL in ssl_certificate and cache them
   ssl_stapling on;
   ssl_stapling_verify on;
   ssl_dhparam /etc/ssl/certs/dhparam.pem;

   add_header X-Early-Data $tls1_3_early_data;
   
   root /opt/mastodon/web/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 image/svg+xml image/x-icon;
   
   add_header Strict-Transport-Security "max-age=31536000" always;

  location / {
    try_files $uri @proxy;
  }

  location ~ ^/(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;
    root /opt/mastodon/;
    try_files $uri @proxy;
  }

  location ~ ^/(emoji|packs) {
    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;
}

# This block is useful for debugging TLS v1.3. Please feel free to remove this
# and use the `$ssl_early_data` variable exposed by NGINX directly should you
# wish to do so.
map $ssl_early_data $tls1_3_early_data {
  "~." $ssl_early_data;
  default "";
}

完成后,按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

验证 Nginx 配置文件语法。

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

重新启动 Nginx 服务器。

$ sudo systemctl restart nginx

第 8 步 - 启动 Mastodon

Tootctl CLI 工具

Tootctl CLI 工具用于在 Mastodon 上执行管理任务。我们需要使其能够在主机 shell 上访问。

创建文件 /usr/local/bin/tootctl 并打开它进行编辑。

$ sudo nano /usr/local/bin/tootctl

将以下代码粘贴到其中。

#!/bin/bash
docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl "$@"

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

授予文件可执行权限。

$ sudo chmod +x /usr/local/bin/tootctl

乳齿象服务文件

您可以使用 Docker compose 命令启动 Mastodon 容器,但通过 systemd 单元文件更容易。

创建并打开 Mastodon 服务文件进行编辑。

$ sudo nano /etc/systemd/system/mastodon.service

将以下代码粘贴到其中。

[Unit]
Description=Mastodon service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes

WorkingDirectory=/opt/mastodon
ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml up -d
ExecStop=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml down

[Install]
WantedBy=multi-user.target

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

重新加载系统守护进程以启动服务文件。

$ sudo systemctl daemon-reload

启用并启动 Mastodon 服务。

$ sudo systemctl enable --now mastodon.service

检查 Docker 容器的状态。

$ watch docker compose -f /opt/mastodon/docker-compose.yml ps

一旦容器的状态更改为正在运行(正常),请按Ctrl + C退出屏幕。

为 Mastodon 创建管理员用户并记下提供的密码。

$ tootctl accounts create navjot --email [email  --confirmed --role Owner
OK
New password: 1338afbe1b4e06e823b6625da80cb537

如果要关闭用户注册,请使用以下命令。

$ tootctl settings registrations close

要再次打开注册,请发出以下命令。

$ tootctl settings registrations open

初始化搜索

在创建和填充 Elasticsearch 索引之前,您需要发出嘟嘟声。发出嘟嘟声后,发出以下命令。

$ tootctl search deploy

您可能会收到以下错误。

/opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/progress.rb:76:in `total=': You can't set the item's total value to less than the current progress. (ProgressBar::InvalidProgressError)
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:178:in `block in update_progress'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/output.rb:43:in `with_refresh'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:177:in `update_progress'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/ruby-progressbar-1.11.0/lib/ruby-progressbar/base.rb:101:in `total='
        from /opt/mastodon/lib/mastodon/search_cli.rb:67:in `deploy'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:116:in `invoke'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:243:in `block in subcommand'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
        from /opt/mastodon/vendor/bundle/ruby/3.0.0/gems/thor-1.2.1/lib/thor/base.rb:485:in `start'
        from /opt/mastodon/bin/tootctl:8:in `<main>'

在这种情况下,进入网站容器 shell。

$ docker exec -it mastodon-website-1 /bin/bash

运行以下命令。

$ sed -E '/progress.total = /d' -i lib/mastodon/search_cli.rb

退出容器外壳。

$ exit

再次运行 Elasticsearch 部署命令。有时该命令可能稍后才起作用。这是 Mastodon 持续存在的问题,因此目前还没有明确的解决方案。

$ tootctl search deploy
Done! 1/?? |-=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=|  ETA: ??:??:?? (0 docs/s)
Indexed 1 records, de-indexed 0

额外的帮手服务

让我们创建另一个服务来删除下载的媒体文件。

创建并打开 Mastodon 媒体删除服务进行编辑。

$ sudo nano /etc/systemd/system/mastodon-media-remove.service

将以下代码粘贴到其中。

[Unit]
Description=Mastodon - media remove service
Wants=mastodon-media-remove.timer

[Service]
Type=oneshot
StandardError=null
StandardOutput=null

WorkingDirectory=/opt/mastodon
ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl media remove

[Install]
WantedBy=multi-user.target

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

如果您想安排媒体删除,可以为其设置计时器服务。

$ sudo nano /etc/systemd/system/mastodon-media-remove.timer

粘贴以下代码。

[Unit]
Description=Schedule a media remove every week

[Timer]
Persistent=true
OnCalendar=Sat *-*-* 00:00:00
Unit=mastodon-media-remove.service

[Install]
WantedBy=timers.target

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

您可以设置另一个服务来删除使用 OpenGraph 标签生成的丰富预览卡。

$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.service

粘贴以下代码。

[Unit]
Description=Mastodon - preview cards remove service
Wants=mastodon-preview_cards-remove.timer

[Service]
Type=oneshot
StandardError=null
StandardOutput=null

WorkingDirectory=/opt/mastodon
ExecStart=/usr/bin/docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl preview_cards remove

[Install]
WantedBy=multi-user.target

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

设置相应的定时服务。

$ sudo nano /etc/systemd/system/mastodon-preview_cards-remove.timer

粘贴以下代码。

[Unit]
Description=Schedule a preview cards remove every week

[Timer]
Persistent=true
OnCalendar=Sat *-*-* 00:00:00
Unit=mastodon-preview_cards-remove.service

[Install]
WantedBy=timers.target

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

重新加载系统守护进程。

$ sudo systemctl daemon-reload

启用并启动计时器。

$ sudo systemctl enable --now mastodon-preview_cards-remove.timer
$ sudo systemctl enable --now mastodon-media-remove.timer

列出所有计时器以检查 Mastodon 服务的时间表。

$ systemctl list-timers
.....
Sat 2024-01-06 00:00:00 UTC 4 days left -                           -                  mastodon-media-remove.timer         mastodon-media-remove.service
Sat 2024-01-06 00:00:00 UTC 4 days left -                           -                  mastodon-preview_cards-remove.timer mastodon-preview_cards-remove.service

访问乳齿象

访问 URL https://mastodon.example.com 来访问您的实例,您将看到类似的页面。

在上面的屏幕截图中,您可以看到有 0 个用户。这是因为我们还没有登录。即使您创建了管理员帐户,它也不会在第一次运行时显示在主页上。为此,请登录您的实例,您将进入以下页面。

单击右侧边栏中的首选项选项以访问设置。从那里,单击左侧菜单中的管理选项以访问 Mastodon 的管理面板。

单击左侧边栏中的服务器设置选项。

在这里,填写您的联系人用户名和企业电子邮件,这些信息现在将反映在您服务器的主页上。还可以填写各种其他信息,包括服务器描述、徽标和服务器规则,以自定义您的 Mastodon 实例。

第 9 步 - 乳齿象维护

要查看 Mastodon 实例的性能和日志,请访问 https://mastodon.example.com/sidekiq/。

您可以在此处查看与 Mastodon 实例相关的各种进程和计划任务的列表。您还可以在死亡或重试部分下检查失败的任务。它还会告诉您实例的内存使用情况。

您可以从 https://mastodon.example.com/pghero/ 检查实例数据库的运行状况。

您可以执行数据库维护、运行 SQL 查询以及删除未使用的索引。要启用查询统计,请点击上面页面上的启用按钮,您将得到以下信息。

切换到root用户。

$ sudo -i su

切换到 /opt/mastodon/database/postgresql 目录。

$ cd /opt/mastodon/database/postgresql

打开 postgresql.conf 文件。

$ nano postgresql.conf

找到行 #shared_preload_libraries='' # (change require restart) 并将其替换为以下内容。

shared_preload_libraries = 'pg_stat_statements'

在文件末尾添加以下行。

pg_stat_statements.track = all

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

重新启动 Mastodon 容器。

$ systemctl restart mastodon.service

退出根 shell。

$ exit

如果你检查数据库健康页面,你可以看到现在是否有任何缓慢的查询。

注意:您还可以从首选项菜单启动 PgHero 和 Sidekiq URL。

如果您的站点由于某种原因无法加载,您可以检查 Docker 生成的日志。

$ docker logs <container-name>

第10步 - 备份乳齿象

我们将使用名为 Restic 的第三方工具来备份 Mastodon。使用 Restic 进行备份的第一步是将所有文件和目录添加到存储库列表中。

创建并打开存储库列表文件进行编辑。

$ sudo nano /opt/mastodon/backup-files

将以下行粘贴到其中。

/etc/nginx
/etc/letsencrypt
/etc/systemd/system
/root
/opt/mastodon/database/pgbackups
/opt/mastodon/*.env
/opt/mastodon/docker-compose.yml
/opt/mastodon/branding
/opt/mastodon/database/redis
/opt/mastodon/web/system
/opt/mastodon/backup-files
/opt/mastodon/mastodon-backup

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

安装 Restic。

$ sudo apt install restic

创建备份存储库并创建初始备份。我们正在将数据备份到 S3 服务。

$ restic -r s3:https://$SERVER:$PORT/mybucket init
$ restic -r s3:https://$SERVER:$PORT/mybucket backup $(cat /opt/mastodon/backup-files) --exclude  /opt/mastodon/database/postgresql

创建 Mastodon 备份服务计时器并打开它进行编辑。

$ sudo nano /etc/systemd/system/mastodon-backup.timer

将以下代码粘贴到其中。

[Unit]
Description=Schedule a mastodon backup every hour

[Timer]
Persistent=true
OnCalendar=*:00:00
Unit=mastodon-backup.service

[Install]
WantedBy=timers.target

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

创建 Mastodon 备份服务文件并打开它进行编辑。

$ sudo nano /etc/systemd/system/mastodon-backup.service

将以下代码粘贴到其中。

[Unit]
Description=Mastodon - backup service
# Without this, they can run at the same time and race to docker compose,
# double-creating networks and failing due to ambiguous network definition
# requiring `docker network prune` and restarting
After=mastodon.service

[Service]
Type=oneshot
StandardError=file:/var/log/mastodon-backup.err
StandardOutput=file:/var/log/mastodon-backup.log

WorkingDirectory=/opt/mastodon
ExecStart=/bin/bash /opt/mastodon/mastodon-backup

[Install]
WantedBy=multi-user.target

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

接下来,创建并打开 /opt/mastodon/mastodon-backup 文件进行编辑。这包含实际的备份命令。

$ sudo nano /opt/mastodon/mastodon-backup

将以下代码粘贴到其中。

#!/bin/bash

set -e

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
SERVER=
PORT=
RESTIC_PASSWORD_FILE=/root/restic-pasword

docker compose -f /opt/mastodon/docker-compose.yml run --rm postgresql sh -c "pg_dump -Fp  mastodon | gzip > /backups/dump.sql.gz"
restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root backup $(cat /opt/mastodon/backup-files) --exclude  /opt/mastodon/database/postgresql
restic -r s3:https://$SERVER:$PORT/mybucket --cache-dir=/root forget --prune --keep-hourly 24 --keep-daily 7 --keep-monthly 3

按 Ctrl + X 并在出现提示时输入 Y 来保存文件。

为备份脚本授予可执行权限。

$ sudo chmod +x /opt/mastodon/mastodon-backup

重新加载服务守护进程并启动备份服务和计时器。

$ sudo systemctl daemon-reload
$ sudo systemctl enable --now mastodon-backup.service
$ sudo systemctl enable --now mastodon-backup.timer

使用以下命令确认每小时备份正在进行并可访问。

$ restic -r s3:https://$SERVER:$PORT/mybucket snapshots
$ restic -r s3:https://$SERVER:$PORT/mybucket mount /mnt

第 11 步 - 升级 Mastodon

升级 Mastodon 需要几个步骤。首先,切换到目录。

$ cd /opt/mastodon

拉取 Mastodon 的最新容器镜像。

$ docker compose pull

如果需要,可以对 docker-compose.yml 进行任何更改。

执行所有数据库迁移。

$ docker compose run --rm shell bundle exec rake db:migrate

更新静态文件的副本。

$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"

重新启动 Mastodon 容器。

$ sudo systemctl restart mastodon.service

上述说明是通用更新说明。请务必检查 Mastodon 的 GitHub 发布页面,查找版本之间的任何特定更新任务和命令,以确保一切顺利进行。

结论

关于在 Debian 12 服务器上使用 Docker 安装 Mastodon 社交网络的教程到此结束。如果您有任何疑问,请在下面的评论中发表。

©2015-2025 Norria support@alaica.com