如何在 Rocky Linux 9 上使用 Docker 安装 Mastodon 社交网络如何在 Rocky Linux 9 上使用 Docker 安装 Mastodon 社交网络如何在 Rocky Linux 9 上使用 Docker 安装 Mastodon 社交网络如何在 Rocky Linux 9 上使用 Docker 安装 Mastodon 社交网络
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何在 Rocky Linux 9 上使用 Docker 安装 Mastodon 社交网络

在此页

  1. 先决条件
  2. 第 1 步 - 配置防火墙
  3. 第 2 步 - 安装 Docker 和 Docker Compose
  4. 第 3 步 - 准备安装
  5. 第 4 步 - 安装 Mastodon
    1. 创建目录并设置所有权
    2. 创建环境和 docker compose 文件
    3. 创建应用程序机密
    4. Mastodon 环境文件
    5. 准备乳齿象

    1. Tootctl CLI 工具
    2. Mastodon 服务文件
    3. 初始化搜索
    4. 额外的助手服务
    5. 访问 Mastodon

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

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

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

    先决条件

    • A server running Rocky Linux 9 with a minimum of 2 CPU cores and 2GB of memory. You will need to upgrade the server as per requirements.

    • A non-root user with sudo privileges.

    • A fully qualified domain name (FQDN) pointing to your server. For our purposes, we will use mastodon.example.com as the domain name.

    • Mastodon sends email notifications to users. We will recommend you use a 3rd party Transactional mail service like Mailgun, Sendgrid, Amazon SES, or Sparkpost. The instructions in the guide will be using Amazon SES.

    • Make sure everything is updated.

      $ sudo dnf update
      
    • Install basic utility packages. Some of them may already be installed.

      $ sudo dnf install wget curl nano unzip yum-utils -y
      

    第 1 步 - 配置防火墙

    第一步是配置防火墙。 Rocky Linux 使用 Firewalld 防火墙。检查防火墙状态。

    $ sudo firewall-cmd --state
    running
    

    防火墙适用于不同的区域,公共区域是我们将使用的默认区域。列出防火墙上所有活动的服务和端口。

    $ sudo firewall-cmd --permanent --list-services
    

    它应该显示以下输出。

    cockpit dhcpv6-client ssh
    

    Wiki.js 需要 HTTP 和 HTTPS 端口才能运行。打开它们。

    $ sudo firewall-cmd --permanent --add-service=http
    $ sudo firewall-cmd --permanent --add-service=https
    

    添加伪装,因为应用程序将联系其他实例。

    $ sudo firewall-cmd --permanent --add-masquerade
    

    重新加载防火墙以应用更改。

    $ sudo firewall-cmd --reload
    

    第 2 步 - 安装 Docker 和 Docker Compose

    Rocky Linux 附带旧版本的 Docker。要安装最新版本,首先,安装官方 Docker 存储库。

    $ sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    

    安装最新版本的 Docker。

    $ sudo dnf install docker-ce docker-ce-cli containerd.io
    

    在尝试安装 Docker 时,您可能会遇到以下错误。

    ror: 
     Problem: problem with installed package buildah-1:1.26.2-1.el9_0.x86_64
      - package buildah-1:1.26.2-1.el9_0.x86_64 requires runc >= 1.0.0-26, but none of the providers can be installed
      - package containerd.io-1.6.9-3.1.el9.x86_64 conflicts with runc provided by runc-4:1.1.3-2.el9_0.x86_64
      - package containerd.io-1.6.9-3.1.el9.x86_64 obsoletes runc provided by runc-4:1.1.3-2.el9_0.x86_64
      - cannot install the best candidate for the job
    

    如果出现上述错误,请使用以下命令。

    $ sudo dnf install docker-ce docker-ce-cli containerd.io docker-compose-plugin --allowerasing
    

    启用并运行 Docker 守护进程。

    $ sudo systemctl enable docker --now
    

    验证它是否正在运行。

    ? docker.service - Docker Application Container Engine
         Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
         Active: active (running) since Sat 2022-11-12 00:19:44 UTC; 6s ago
    TriggeredBy: ? docker.socket
           Docs: https://docs.docker.com
       Main PID: 99263 (dockerd)
          Tasks: 8
         Memory: 28.1M
            CPU: 210ms
         CGroup: /system.slice/docker.service
                 ??99263 /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 wheel docker
    

    第 3 步 - 准备安装

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

    $ 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
    $ sudo sysctl --load /etc/sysctl.d/90-max_map_count.conf
    

    配置 SELinux 以允许网络连接。

    $ sudo setsebool -P httpd_can_network_connect 1
    

    第 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 组合文件以进行编辑。

    $ sudo nano docker-compose.yml
    

    将以下代码粘贴到其中。

    version: '3'
    
    services:
      postgresql:
        image: postgres:15-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.7
        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
        ulimits:
          memlock:
            soft: -1
            hard: -1
        healthcheck:
          test: ["CMD-SHELL", "nc -z elasticsearch 9200"]
        volumes:
          - elasticsearch:/usr/share/elasticsearch/data
        networks:
          - internal_network
    
      website:
        image: tootsuite/mastodon:v4.0.2
        env_file:
          - application.env
          - database.env
        command: bash -c "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.0.2
        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.0.2
        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.0.2
        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.0.2。查看 Mastodon GitHub Releases 页面并适当调整 Docker compose 文件中的版本。我们还使用最新版本的 PostgreSQL 和 Redis。您可以根据您的要求调整它们。我们目前正在使用 Elasticsearch 7.x。您可以在 Docker Hub 页面上关注 Elasticsearch 的主要版本,因此您必须不断手动更新它以获取与 Java 相关的安全更新。

    internal: true 不适用于 firewalld,这就是它在上面的文件中被注释掉的原因。如果此问题得到解决,您可以重新添加该附加限制。

    创建应用程序机密

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

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

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

    您也可以使用 openssl 实用程序。

    $ openssl rand -hex 64
    

    使用以下命令生成 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
    

    Mastodon 环境文件

    打开 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=AKIA3FIG4NVFNSC3AHXE
    SMTP_PASSWORD=BHM4MVOjBmnGhSJ9lH3PAXKJ/9AiLWcUghG/kEN2kkFo
    
    
    # secrets
    SECRET_KEY_BASE=c09fa403575e0b431e54a2e228f20cd5a5fdfdbba0da80598959753b829a4e3c0266eedbac7e3cdf9f3345db36c56302c0e1bc5bfc8c5d516be59a2c41de7e37
    OTP_SECRET=febb7dbb0d3308094083733fc923a430e52ccec767d48d7d2e0c577bfcb6863dbdfc920b1004b1f8c2967b9866bd7a0b4a15460f9fc7687aa4a42acf54e5a3d4
    
    # Changing VAPID keys will break push notifications
    VAPID_PRIVATE_KEY=13RgrfOY2tkwuUycylDPOkoHennkJ0ZAPV_fUwDy7-g=
    VAPID_PUBLIC_KEY=BDAQuGwPbh1kbCV904adYXHvz9lLRaJHkiQkihRDPyBn3QmkAYbR21WHYoP8TkyG6dylG6IXpEVfLwdoW7fJVns=
    

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

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

    $ sudo nano database.env
    

    在其中粘贴以下行。

    # postgresql configuration
    POSTGRES_USER=mastodon
    POSTGRES_DB=mastodon
    POSTGRES_PASSWORD=15ff12dcb93aa60680d2aadb4032ee
    PGPASSWORD=15ff12dcb93aa60680d2aadb4032ee
    PGPORT=5432
    PGHOST=postgresql
    PGUSER=mastodon
    
    # pgbouncer configuration
    #POOL_MODE=transaction
    #ADMIN_USERS=postgres,mastodon
    #DATABASE_URL="postgres://mastodon::5432/mastodon"
    
    # elasticsearch
    ES_JAVA_OPTS=-Xms512m -Xmx512m
    ELASTIC_PASSWORD=13382e99f6b2d4dc7f3d66e4b9872d
    
    # mastodon database configuration
    #DB_HOST=pgbouncer
    DB_HOST=postgresql
    DB_USER=mastodon
    DB_NAME=mastodon
    DB_PASS=15ff12dcb93aa60680d2aadb4032ee
    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=13382e99f6b2d4dc7f3d66e4b9872d
    

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

    准备乳齿象

    准备好 Nginx 提供的静态文件。

    $ 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
    

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

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

    第 5 步 - 安装 Nginx

    Rocky Linux 附带旧版本的 Nginx。您需要下载官方 Nginx 存储库以安装最新版本。

    创建并打开 /etc/yum.repos.d/nginx.repo 文件以创建官方 Nginx 存储库。

    $ sudo nano /etc/yum.repos.d/nginx.repo
    

    将以下代码粘贴到其中。

    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    
    [nginx-mainline]
    name=nginx mainline repo
    baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=0
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    

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

    安装 Nginx 服务器。

    $ sudo dnf install nginx
    

    验证安装。

    $ nginx -v
    nginx version: nginx/1.22.1
    

    启用并启动 Nginx 服务器。

    $ sudo systemctl enable nginx --now
    

    检查服务器的状态。

    $ sudo systemctl status nginx
    ? nginx.service - nginx - high performance web server
         Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
         Active: active (running) since Sun 2022-11-13 13:49:55 UTC; 1s ago
           Docs: http://nginx.org/en/docs/
        Process: 230797 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
       Main PID: 230798 (nginx)
          Tasks: 3 (limit: 12355)
         Memory: 2.8M
            CPU: 13ms
         CGroup: /system.slice/nginx.service
                 ??230798 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
                 ??230799 "nginx: worker process"
                 ??230800 "nginx: worker process"
    

    第 6 步 - 安装 SSL

    Certbot 工具使用 Lets Encrypt API 生成 SSL 证书。它需要 EPEL 存储库才能工作。

    $ sudo dnf install epel-release
    

    我们将使用 Snapd 安装 Certbot。安装快照。

    $ sudo dnf install snapd
    

    启用并启动 Snap 服务。

    $ sudo systemctl enable snapd --now
    

    安装 Snap 核心包。

    $ sudo snap install core
    $ sudo snap refresh core
    

    为 Snapd 工作创建必要的链接。

    $ sudo ln -s /var/lib/snapd/snap /snap
    $ echo 'export PATH=$PATH:/var/lib/snapd/snap/bin' | sudo tee -a /etc/profile.d/snapd.sh
    

    发出以下命令以安装 Certbot。

    $ sudo snap install --classic certbot
    

    通过创建指向其可执行文件的符号链接来启用 Certbot。

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

    生成 SSL 证书。

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

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

    生成 Diffie-Hellman 组证书。

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

    要检查 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 http2;
       server_name mastodon.example.com;
       
       access_log  /var/log/nginx/mastodon.access.log;
       error_log   /var/log/nginx/mastodon.error.log;
    
       http2_push_preload on; # Enable HTTP/2 Server Push
    
       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
    

    如果您收到以下错误,则很可能是由于 SELinux 限制。

    nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied)
    

    要修复错误,请运行以下命令。

    $ sudo ausearch -c 'nginx' --raw | audit2allow -M my-nginx
    $ sudo semodule -X 300 -i my-nginx.pp
    

    再次启动 Nginx 服务。

    $ sudo systemctl start 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
    

    Mastodon 服务文件

    您可以使用 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
    

    一旦容器的状态更改为 running (healthy),按 Ctrl + C 退出屏幕。

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

    $ tootctl accounts create navjot --email  --confirmed --role admin
    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>'
    

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

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

    运行以下命令。

    $ sed -E 's/indices.sum.+/2000/g' -i lib/mastodon/search_cli.rb
    

    退出容器外壳。

    $ exit
    

    再次运行 Elasticsearch 部署命令。

    $ tootctl search deploy
    

    额外的帮手服务

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

    创建并打开 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 标签生成的 Rich 预览卡。

    $ 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
    

    访问乳齿象

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

    在上面的屏幕截图中,您可以看到有 2 个用户,其中 1 个(我)被设置为管理员。通常情况并非如此。即使您创建了管理员帐户,它也不会在首次运行时显示在主页上。为此,请登录到您的实例,您将被带到以下页面。

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

    单击左侧栏中的站点设置选项。

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

    第 9 步 - Mastodon 维护

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

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

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

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

    切换到根用户。

    $ sudo -i su
    

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

    $ cd /opt/mastodon/database/postgresql
    

    打开 postgresql.conf 文件。

    $ nano postgresql.conf
    

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

    shared_preload_libraries = 'pg_stat_statements'
    

    在文件末尾添加以下行。

    pg_stat_statements.track = all
    

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

    重新启动 Mastodon 容器。

    $ systemctl restart mastodon.service
    

    退出根外壳。

    $ exit
    

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

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

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

    $ docker logs <container-name>
    

    第 10 步 - 备份 Mastodon

    我们将使用名为 Restic 的第 3 方工具来备份 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 dnf 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 发布页面,以查找版本之间的任何特定更新任务和命令,以确保一切顺利进行。

    结论

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

©2015-2025 艾丽卡 support@alaica.com