Поиск по сайту:

Как установить социальную сеть Mastodon с Docker на Rocky Linux 9


На этой странице

  1. Предпосылки
  2. Шаг 1. Настройка брандмауэра
  3. Шаг 2. Установите Docker и Docker Compose
  4. Шаг 3. Подготовка к установке
  5. Шаг 4. Установите Mastodon
    1. Создание каталогов и установка владельцев
    2. Создание окружения и файлов docker compose
    3. Создание секретов приложения
    4. Файлы среды Mastodon
    5. Подготовить мастодонта

    1. Инструмент интерфейса командной строки Tooctl
    2. Служебный файл Mastodon
    3. Инициализировать поиск
    4. Дополнительные вспомогательные услуги
    5. Доступ к мастодонту

    Mastodon — бесплатная, децентрализованная социальная сеть с открытым исходным кодом. Он был создан как альтернатива Twitter. Как и в Twitter, люди могут подписываться друг на друга и публиковать сообщения, изображения и видео. Но, в отличие от Твиттера, здесь нет центрального хранилища или авторитета для контента.

    Вместо этого Mastodon работает на тысячах разных серверов, каждый из которых управляется разными членами сообщества. Пользователи, зарегистрированные на одном сервере, могут легко подключаться к пользователям в другой сети и следить друг за другом в разных экземплярах.

    Любой может установить свой экземпляр сервера Mastodon. В этом руководстве вы узнаете, как настроить экземпляр Mastodon на сервере с Rocky Linux 9 с помощью Docker. 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 Firewall. Проверьте состояние брандмауэров.

    $ 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. Если вы хотите избежать использования sudo при каждом запуске команды docker, добавьте свое имя пользователя в docker группа.

    $ sudo usermod -aG docker $(whoami)
    

    Вам нужно будет выйти из сервера и снова войти в систему под тем же пользователем, чтобы включить это изменение, или использовать следующую команду.

    $ su - ${USER}
    

    Подтвердите, что ваш пользователь добавлен в группу Docker.

    $ groups
    navjot wheel docker
    

    Шаг 3 — Подготовка к установке

    Ограничение количества mmap по умолчанию для Elasticsearch очень низкое. Выполните следующую команду, чтобы проверить значение по умолчанию.

    $ 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 и сопутствующих услуг.

    $ 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 и backup.

    $ 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
    

    Создание окружения и файлов компоновки докеров

    Создайте файлы среды для приложения и базы данных.

    $ 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. Мы также используем последние версии PostgreSQL и Redis. Вы можете настроить их в соответствии с вашими требованиями. На данный момент мы используем Elasticsearch 7.x. Нет основной версии Elasticsearch, за которой вы можете следить на странице Docker Hub, поэтому вам придется постоянно обновлять ее вручную для получения обновлений безопасности, связанных с 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
    

    Подождите, пока запустится (работоспособен), затем нажмите 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 генерирует SSL-сертификаты с помощью Lets Encrypt API. Для работы требуется репозиторий 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 на вашем сервере.

    Создайте групповой сертификат Диффи-Хеллмана.

    $ 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 — Запуск мастодонта

    Инструмент интерфейса командной строки Tootctl

    Инструмент командной строки Tootctl используется для выполнения административных задач в Mastodon. Нам нужно сделать его доступным в оболочке хоста.

    Создайте файл /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

    Вы можете запустить контейнеры Mastodon с помощью команды Docker compose, но это проще сделать с помощью файла модуля 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  --confirmed --role admin
    OK
    New password: 1338afbe1b4e06e823b6625da80cb537
    

    Если вы хотите закрыть регистрацию пользователей, используйте следующую команду.

    $ tootctl settings registrations close
    

    Чтобы снова открыть регистрации, введите следующую команду.

    $ tootctl settings registrations open
    

    Инициализировать поиск

    Прежде чем вы сможете создавать и заполнять индексы Elasticsearch, вам нужно будет создать файл Toot. После того, как вы сделали гудок, введите следующую команду.

    $ 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.

    $ 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 из них (я) настроен как администратор. Обычно это не так. Даже если вы создаете учетную запись администратора, она не отображается на главной странице при первом запуске. Для этого войдите в свой экземпляр, и вы попадете на следующую страницу.

    Нажмите на опцию Preferences на правой боковой панели, чтобы получить доступ к настройкам. Оттуда нажмите на опцию «Администрирование» в левом меню, чтобы получить доступ к панели администрирования Mastodons.

    Нажмите на опцию «Настройки сайта» на левой боковой панели.

    Здесь введите свое контактное имя пользователя и рабочий адрес электронной почты, которые теперь будут отображаться на домашней странице вашего сервера. Также заполните различную другую информацию, включая описание сервера, логотип и правила сервера, чтобы настроить свой экземпляр 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=# (для изменения требуется перезагрузка) и замените ее следующей.

    shared_preload_libraries = 'pg_stat_statements'
    

    Добавьте следующую строку в конец файла.

    pg_stat_statements.track = all
    

    Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.

    Перезапустите контейнеры Mastodon.

    $ systemctl restart mastodon.service
    

    Выйдите из корневой оболочки.

    $ exit
    

    Если вы проверите страницу работоспособности базы данных, вы увидите, есть ли сейчас какие-либо медленные запросы.

    Примечание. Вы также можете запустить URL-адреса PgHero и Sidekiq из меню «Настройки».

    Если ваш сайт по какой-то причине не загружается, вы можете проверить журналы, созданные 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 при появлении запроса.

    Установите Рестик.

    $ 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 требует нескольких шагов. Сначала переключитесь в каталог.

    $ 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, чтобы найти какие-либо конкретные задачи обновления и команды между версиями, чтобы убедиться, что все идет гладко.

    Заключение

    На этом мы завершаем наше руководство по установке Mastodon Social Network с помощью Docker на сервер Rocky Linux 9. Если у вас есть какие-либо вопросы, задайте их в комментариях ниже.