Установка Mastodon на Debian 12 с помощью Docker
Mastodon — свободная, децентрализованная и открытая социальная сеть, альтернатива Twitter. Интерфейс и принципы схожи: пользователи подписываются друг на друга и публикуют тексты, изображения и видео. В отличие от централизованных платформ, Mastodon работает через множество серверов (инстансов), управляемых сообществом. Любой может установить свой сервер Mastodon.
Эта инструкция покажет, как установить Mastodon на Debian 12 с помощью Docker. Docker упрощает установку, потому что все необходимые сервисы упакованы в контейнеры.
Важно: перед началом убедитесь, что у вас есть резервная копия всех важных данных и что вы понимаете назначение каждой команды. В руководстве используются примеры домена и секретов — замените их на свои значения.
Что вы получите в конце
- Рабочий Mastodon-инстанс на Debian 12
- Настроенный Nginx с HTTPS (Let’s Encrypt)
- Сервисы: PostgreSQL, Redis, Elasticsearch, веб/процесс, стриминг, workers
- Автоматическое обновление сертификатов, базовое резервное копирование и задачи обслуживания
Важно: инструкции обновлялись для стабильных релизов на момент написания. Перед установкой проверьте совместимость версий (Mastodon, Docker, Elasticsearch и т. д.).
Основные термины (1‑строчные определения)
- Инстанс — отдельный сервер Mastodon, работающий под своим доменом.
- Docker Compose — инструмент для запуска многоконтейнерных приложений через YAML-файл.
- Elasticsearch — сервис поиска, используемый Mastodon для индексирования постов.
Требования
- Сервер с Debian 12, минимум 2 CPU, 2 ГБ RAM (рекомендуется больше по мере роста). Обновляйте ресурсы по потребности.
- Нерутовый пользователь с sudo-привилегиями.
- Полностью квалифицированное доменное имя (FQDN), указывающее на сервер (в примерах: mastodon.example.com).
- Транзакционный почтовый сервис (Mailgun/SendGrid/Amazon SES и т. п.) — в инструкции используется 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Контрольный список перед началом
- Домен указывает на сервер (A/AAAA запись)
- Пользователь с sudo есть
- Открыты порты SSH/HTTP/HTTPS в провайдере
- Имеется доступ к транзакционной почте
- Есть план резервного копирования
Debian поставляется с ufw (Uncomplicated Firewall). Проверьте статус:
$ sudo ufw statusВы увидите “Status: inactive” при первой проверке.
Разрешите SSH, чтобы не потерять соединение при включении фильтрации:
$ sudo ufw allow OpenSSHРазрешите HTTP и HTTPS:
$ sudo ufw allow http
$ sudo ufw allow httpsВключите ufw:
$ sudo ufw enableПроверьте снова:
$ sudo ufw statusОжидаемый вывод покажет OpenSSH, 80/tcp и 443 разрешёнными для IPv4/IPv6.
Важно: если у вас нестандартный SSH-порт, замените правило OpenSSH соответствующим портом.
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Обновляем списки пакетов и устанавливаем Docker:
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginПроверяем состояние службы Docker:
$ sudo systemctl status dockerЧтобы не запускать docker с sudo, добавьте пользователя в группу docker и перелогиньтесь:
$ sudo usermod -aG docker $(whoami)
$ su - ${USER}Проверьте группы:
$ groups
navjot sudo users dockerElasticsearch требует увеличенного лимита mmap. Проверьте текущее значение:
$ sudo sysctl 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Создание директорий и прав
Создаём каталоги для базы данных, бэкапов, веб-данных и брендинга:
$ sudo mkdir -p /opt/mastodon/database/{postgresql,pgbackups,redis,elasticsearch}
$ sudo mkdir -p /opt/mastodon/web/{public,system}
$ sudo mkdir -p /opt/mastodon/brandingУстанавливаем владельцев для некоторых директорий (как в официальном образе Mastodon):
$ sudo chown 991:991 /opt/mastodon/web/{public,system}
$ sudo chown 1000 /opt/mastodon/database/elasticsearch
$ sudo chown 70:70 /opt/mastodon/database/pgbackupsПерейдём в /opt/mastodon:
$ cd /opt/mastodonСоздание файлов окружения и docker-compose.yml
Создайте пустые файлы окружения:
$ sudo touch application.env database.envОткройте редактор и создайте docker-compose.yml:
$ sudo nano docker-compose.ymlВставьте в файл содержимое для сервисов: PostgreSQL, Redis (volatile и persistent), Elasticsearch, website, shell, streaming и sidekiq, а также сети и volumes. (В исходном примере используется tootsuite/mastodon:v4.2.3 и elasticsearch 7.17.16.)
Сохраните файл. Обратите внимание на binding томов к /opt/mastodon и на проброс портов 127.0.0.1:3000/4000/9200 — это намеренно, чтобы внешняя сеть общалась через Nginx.
Примечание: проверьте страницу релизов Mastodon и обновите тег образа, если необходимо.
Создание секретов приложения
Сгенерируйте SECRET_KEY_BASE и OTP_SECRET (пример с rake secret):
$ docker compose run --rm shell bundle exec rake secretАльтернативно можно использовать openssl:
$ openssl rand -hex 64Сгенерируйте VAPID ключи для WebPush:
$ docker compose run --rm shell bundle exec rake mastodon:webpush:generate_vapid_keyСоздайте пароли для PostgreSQL и Elasticsearch:
$ openssl rand -hex 15Файлы окружения Mastodon
Откройте application.env:
$ sudo nano application.envПример содержимого (замените домен, секреты и SMTP на свои значения):
# 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
# locale
DEFAULT_LOCALE=en
# email (пример для Amazon SES)
SMTP_SERVER=email-smtp.us-west-2.amazonaws.com
SMTP_PORT=587
SMTP_LOGIN=AKIA...YOUR_KEY
SMTP_PASSWORD=YOUR_SMTP_PASSWORD
SMTP_FROM_ADDRESS=[email protected]
# secrets
SECRET_KEY_BASE=<>
OTP_SECRET=<>
# VAPID keys
VAPID_PRIVATE_KEY=<>
VAPID_PUBLIC_KEY=<>
# IP and session retention
IP_RETENTION_PERIOD=2592000
SESSION_RETENTION_PERIOD=2592000 Обновите database.env:
$ sudo nano database.envПример:
# postgresql configuration
POSTGRES_USER=mastodon
POSTGRES_DB=mastodon
POSTGRES_PASSWORD=<>
PGPASSWORD=<>
PGPORT=5432
PGHOST=postgresql
PGUSER=mastodon
# elasticsearch
ELASTIC_PASSWORD=<>
# mastodon database configuration
DB_HOST=postgresql
DB_USER=mastodon
DB_NAME=mastodon
DB_PASS=<>
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=<> Замените маркеры на сгенерированные значения.
Подготовка статики и запуск data‑layer
Скопируйте статические файлы из образа в bind‑том для Nginx:
$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"Поднимите слои данных:
$ docker compose up -d postgresql redis redis-volatileДождитесь состояния running (healthy):
$ watch docker compose psИнициализируйте базу данных:
$ docker compose run --rm shell bundle exec rake db:setupЕсли база уже существует, выполните миграции:
$ docker compose run --rm shell bundle exec rake db:migrateДля получения последних версий Nginx подключим официальный архив и установим mainline-ветку.
Импорт ключа и добавление репозитория:
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
$ 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Проверьте версию и запустите Nginx:
$ sudo nginx -v
$ sudo systemctl start nginx
$ sudo systemctl status nginxУстановим Certbot через snap (актуальная версия):
$ sudo apt install snapd
$ sudo snap install core
$ sudo snap refresh core
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
$ certbot --versionЗапрос сертификата для Nginx:
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d mastodon.example.comСертификаты будут в /etc/letsencrypt/live/mastodon.example.com.
Создайте Diffie-Hellman параметры:
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096Проверьте автоматическое обновление сертификатов:
$ sudo certbot renew --dry-runОткройте /etc/nginx/nginx.conf и добавьте строку:
server_names_hash_bucket_size 64;Создайте /etc/nginx/conf.d/mastodon.conf с конфигурацией проксирования, кэширования, правил для статических ресурсов, SSL и OCSP. В конфигурации задаются upstream backend (порт 3000) и streaming (порт 4000), paths для кеша и многое другое. Проверьте синтаксис:
$ sudo nginx -t
$ sudo systemctl restart nginxСовет: держите сокрытие административных URL (sidekiq, pghero) с ограничением доступа по IP или BasicAuth, если это требуется политиками безопасности.
tootctl — удобная обёртка CLI
Создайте скрипт /usr/local/bin/tootctl, чтобы запускать tootctl внутри контейнера:
#!/bin/bash
docker compose -f /opt/mastodon/docker-compose.yml run --rm shell tootctl "$@"Сделайте его исполняемым:
$ sudo chmod +x /usr/local/bin/tootctlsystemd unit для Mastodon
Создайте /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Перезагрузите демон systemd и включите сервис:
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now mastodon.serviceПроверьте контейнеры:
$ watch docker compose -f /opt/mastodon/docker-compose.yml psСоздайте администратора:
$ tootctl accounts create navjot --email [email protected] --confirmed --role OwnerОтключение/включение регистраций:
$ tootctl settings registrations close
$ tootctl settings registrations openИнициализация поиска (Elasticsearch)
Сделайте хоть один toot (запись), затем:
$ tootctl search deployЕсли команда падает с ошибкой ProgressBar, временное решение — зайти в контейнер сайта и удалить строку, вызывающую проблемы:
$ docker exec -it mastodon-website-1 /bin/bash
$ sed -E '/progress.total = /d' -i lib/mastodon/search_cli.rb
$ exit
$ tootctl search deployЭто workaround; ожидайте фикс в официальном проекте.
Создайте systemd unit для удаления старых медиа:
/ etc / systemd unit mastodon-media-remove.service (пример в исходной инструкции). Настройте timer для еженедельного запуска. То же самое для preview_cards.
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now mastodon-preview_cards-remove.timer
$ sudo systemctl enable --now mastodon-media-remove.timerОткройте https://mastodon.example.com. Примеры страниц — главная, лента, панель администратора. На странице Server settings заполните контактную информацию, описание сервера, логотип и правила.




Мониторинг и админские интерфейсы:
- Sidekiq: https://mastodon.example.com/sidekiq/ — задачи фоновых процессов
- PgHero: https://mastodon.example.com/pghero/ — диагностика запросов, индексов и медленных запросов
Чтобы включить расширенную статистику запросов, в postgresql.conf добавьте pg_stat_statements:
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = allПерезапустите контейнеры Mastodon:
$ sudo systemctl restart mastodon.serviceПросмотр логов контейнера:
$ docker logs В инструкции используется Restic и S3-совместимое хранилище.
Создайте список файлов для бэкапа: /opt/mastodon/backup-files (пример в инструкции). Установите restic:
$ sudo apt install resticИнициализация репозитория и первый бэкап (пример):
$ 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Настройте systemd unit и timer, который запускает скрипт /opt/mastodon/mastodon-backup для архивирования дампа Postgres и бэкапа файлов с последующей очисткой старых снимков. Пример конфигурации таймера — ежечасный запуск.
Проверка снимков:
$ restic -r s3:https://$SERVER:$PORT/mybucket snapshots
$ restic -r s3:https://$SERVER:$PORT/mybucket mount /mntВажное замечание: храните creds (ключи AWS/Restic password) в защищённом месте и используйте переменные окружения или файл с ограниченным доступом.
Обновление обычно включает:
$ cd /opt/mastodon
$ docker compose pull
$ 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 на предмет специальных инструкций миграции между версиями.
- У вас очень маленький сервер (менее 2 ГБ RAM): производительность и стабильность будут низкими.
- Вам нужен полностью управляемый SaaS-подход: в таком случае размещение в облаке или использование хостинг-провайдера Mastodon может быть предпочтительнее.
- Нужны сложные гарантии SLA или горизонтальное масштабирование: потребуется кластеризация баз данных, выделенные Elasticsearch-кластеры и балансировщики.
- Установка Mastodon напрямую на хост (без Docker) — даёт тонкую настройку, но сложнее поддерживать зависимости.
- Использование Kubernetes (Helm) — для production-кластеров с высокой нагрузкой.
- Использование управляемых сервисов (хостинг Mastodon) — минимальные операционные затраты.
- Ограничьте доступ к админ-панели (Sidekiq, PgHero) по IP или через BasicAuth.
- Регулярно применяйте обновления образов Docker и патчи безопасности.
- Храните секреты в менеджере секретов или в файлах с ограниченными правами.
- Для соответствия GDPR: минимизируйте сроки хранения IP (в настройках мы сократили до 30 дней), информируйте пользователей и давайте механизмы удаления данных.
Важно: изменение периодов хранения IP меньше 2 дней требует редактирования планировщика cleanup в config/sidekiq.yml.
- Проверка состояния контейнеров: docker compose ps
- Если база данных недоступна — проверьте логи PostgreSQL: docker logs
- Если Elasticsearch не отвечает — проверьте vm.max_map_count и логи elasticsearch
- При падении Nginx — nginx -t и sudo systemctl status nginx
- При проблемах с сертификатом — sudo certbot renew –dry-run
- Восстановление из резервной копии: используйте restic restore и дамп PostgreSQL (pg_restore/pg_restore -d …)
Для сисадмина перед запуском:
- Настроен DNS
- Открыты порты
- Созданы и защищены секреты
- Работающий бэкап, выполнена пробная реставрация
Для оператора при апгрейде:
- Проверены релиз-ноты
- Сделан бэкап БД и файлов
- Выполнены миграции на тестовой копии (если возможно)
- План возврата (rollback) готов
- Сайт доступен по HTTPS на заданном домене
- Пользователь может зарегистрироваться (если включено) и залогиниться
- Веб-интерфейс отвечает, стриминг работает (вкладки обновляются в реальном времени)
- Sidekiq и PgHero доступны (по защищённому каналу)
- Регулярные бэкапы выполняются и тестовая реставрация успешна
- Сделать полный бэкап (restic + pg_dump)
- Остановить написание контента (опционально закрыть регистрации)
- docker compose pull
- rake db:migrate
- cp -r public/* /static/
- systemctl restart mastodon.service
- Проверить логи и сервисы
- Открыть регистрации
graph TD
A[Планирование установки] --> B{Есть ли опыт с Docker?}
B -- Да --> C[Установка через Docker Compose]
B -- Нет --> D[Рассмотреть managed Mastodon или обучение Docker]
C --> E{Нужен ли масштаб?}
E -- Нет --> F[Single-node Docker подход]
E -- Да --> G[Рассмотреть Kubernetes/Helm и выделенное хранилище]- Для доступа к shell контейнера сайта: docker compose run –rm shell /bin/bash
- Проверка состояния контейнеров: docker compose ps / docker ps
- Просмотр логов: docker logs
- Перезагрузить всё: sudo systemctl restart mastodon.service
- Поддерживайте переменные окружения вне репозитория кода
- Утечка секретов: хранить в защищённом хранилище, ротировать ключи
- Потеря данных: тестировать восстановление из бэкапа регулярно
- Нагрузка: масштабировать по мере роста — использовать распределённый Elasticsearch и отдельную базу
- Указанные в примере значения локали: DEFAULT_LOCALE=en — замените на ru при желании
- Обратите внимание на законы о хранении персональных данных в вашей юрисдикции (Россия/ЕС)
Вы установили Mastodon на Debian 12 с Docker, настроили Nginx с HTTPS, организовали бэкапы и базовые задачи обслуживания. Для production‑окружения рекомендуется увеличить ресурсы сервера, настроить мониторинг, логирование (например, централизованный ELK/Prometheus) и протестировать сценарии восстановления.
Если остались вопросы, опишите конкретную проблему или ошибку, и мы поможем с диагностикой.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента