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

Как установить социальную сеть Mastodon на Debian 12


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

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

Любой может установить свой экземпляр сервера Mastodon. Из этого руководства вы узнаете, как настроить экземпляр Mastodon на сервере с Debian 12 с помощью Docker. Docker упрощает установку Mastodon, помещая все необходимые пакеты и сервисы в контейнеры.

Предварительные условия

    Сервер под управлением Debian 12 с минимум 2 ядрами ЦП и 2 ГБ памяти. Вам нужно будет обновить сервер в соответствии с требованиями.

    Пользователь без полномочий root с привилегиями sudo.

    Полное доменное имя (FQDN), указывающее на ваш сервер. Для наших целей мы будем использовать mastodon.example.com в качестве доменного имени.

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

$ sudo usermod -aG docker $(whoami)

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

$ su - ${USER}

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

$ groups
navjot sudo users docker

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

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

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

$ 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, веб-каталогов и каталогов резервного копирования.

$ 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

Вставьте в него следующий код.

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 и соответствующим образом измените версию в файле компоновки Docker. Мы также используем последние версии 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

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

Откройте файл 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

Установите Нгинкс.

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

Используйте следующую команду, чтобы убедиться, что команда Certbot выполняется, создав символическую ссылку на каталог /usr/bin.

$ 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 на вашем сервере.

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

$ 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 — Запустите Мастодонта

Инструмент CLI Tooctl

Инструмент Tootctl CLI используется для выполнения административных задач на 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 с помощью команды 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 [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>'

В этом случае войдите в оболочку контейнера веб-сайта.

$ 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='' # (для изменения требуется перезагрузка) и замените ее следующей.

shared_preload_libraries = 'pg_stat_statements'

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

pg_stat_statements.track = all

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

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

$ systemctl restart mastodon.service

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

$ exit

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

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

Если ваш сайт по какой-то причине не загружается, вы можете проверить журналы, созданные Docker.

$ docker logs <container-name>

Шаг 10 — Резервное копирование Мастодонта

Для резервного копирования Mastodon мы будем использовать сторонний инструмент под названием Restic. Первым шагом для резервного копирования с помощью 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 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 требует нескольких шагов. Сначала переключитесь в каталог.

$ 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/"

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

$ sudo systemctl restart mastodon.service

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

Заключение

На этом завершается наше руководство по установке социальной сети Mastodon с помощью Docker на сервере Debian 12. Если у вас есть вопросы, задавайте их в комментариях ниже.

Статьи по данной тематике: