Гид по технологиям

Установка Mastodon на Ubuntu 22.04 с Docker — полное руководство

11 min read Самохостинг Обновлено 24 Nov 2025
Mastodon на Ubuntu 22.04 с Docker — руководство
Mastodon на Ubuntu 22.04 с Docker — руководство

Это пошаговое руководство объясняет, как самостоятельно развернуть Mastodon на сервере под управлением Ubuntu 22.04 с использованием Docker и Docker Compose. Включены требования, настройка брандмауэра, установка Docker и Nginx, получение SSL через Certbot, создание файлов окружения, запуск контейнеров, бэкап и инструкции по обновлению и обслуживанию. Для продакшн-развертывания следуйте чек-листам по безопасности и восстановлению.

О чём эта статья

Цель — провести вас от пустого сервера до работающего инстанса Mastodon, готового принимать пользователей и индексировать контент. Статья подходит для системных администраторов и инженеров DevOps с базовыми навыками работы в Linux, Docker и системd.

Важно: команды и примеры конфигураций сохранены в оригинальном виде; замените примеры паролей, домен и ключи на свои значения перед использованием.


Ключевые варианты запроса (SEO)

  • основной: установка Mastodon
  • связанные формулировки: Mastodon Docker Ubuntu, развернуть Mastodon, Mastodon Nginx SSL, бэкап Mastodon, обновление Mastodon

Факто-бокс — ключевые числа и понятия

  • ОС: Ubuntu 22.04
  • Рекомендуемые ресурсы: минимум 2 CPU, 2 ГБ ОЗУ (для теста). Для продакшна — 4+ CPU, 8–16+ ГБ ОЗУ в зависимости от нагрузки.
  • Основные сервисы: PostgreSQL, Redis, Elasticsearch, Sidekiq, Streaming, веб-процесс.
  • Порты, которые будут открыты: 22 (SSH), 80 (HTTP), 443 (HTTPS). Внутренние: 3000, 4000, 9200 (локальные прокси).

Требования (кратко)

  • Сервер с Ubuntu 22.04 и доступом по SSH. Минимум 2 CPU/2 ГБ для тестовой установки.
  • Нерут-пользователь с sudo.
  • FQDN (например, mastodon.example.com), указывающий на сервер.
  • Рекомендованный почтовый провайдер для уведомлений: Amazon SES, Mailgun, SendGrid и т.п. В примерах используется Amazon SES.
  • Базовые утилиты: wget, curl, nano и т.п.

Пример обновления пакетов и установки утилит:

$ sudo apt update
$ sudo apt install wget curl nano software-properties-common dirmngr apt-transport-https gnupg gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -y

Содержание руководства (быстрая навигация)

  • Настройка брандмауэра (ufw)
  • Установка Docker и Docker Compose
  • Подготовка системы (vm.max_map_count)
  • Создание директорий, docker-compose.yml и env-файлов
  • Получение секретов, VAPID-ключей и паролей
  • Настройка Nginx и SSL (Certbot)
  • Конфигурация Nginx для Mastodon
  • Сервис systemd для Mastodon и вспомогательные таймеры
  • Мониторинг (Sidekiq, PgHero), отладка и бэкап (Restic)
  • Обновление и проверка
  • Безопасность, GDPR и рекомендации по обслуживанию

Шаг 1 — Настройка брандмауэра (ufw)

Ubuntu поставляется с ufw (Uncomplicated Firewall). Проверьте статус:

$ sudo ufw status

Если неактивен, разрешите OpenSSH, HTTP и HTTPS и включите ufw:

$ sudo ufw allow OpenSSH
$ sudo ufw allow http
$ sudo ufw allow https
$ sudo ufw enable

Проверьте статус повторно:

$ sudo ufw status

Ожидаемый вывод покажет Allow для OpenSSH, 80/tcp и 443.

Важно: включайте ufw только после разрешения SSH, чтобы не потерять соединение.


Шаг 2 — Установка Docker и Docker Compose

Ubuntu 22.04 может содержать устаревшие пакеты Docker. Установите официальный репозиторий Docker и актуальную версию:

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Проверьте статус Docker:

$ sudo systemctl status docker

Опционально добавьте своего пользователя в группу docker, чтобы не требовать sudo для команд docker:

$ sudo usermod -aG docker $(whoami)
$ su - ${USER}
$ groups

Шаг 3 — Подготовка системы (vm.max_map_count для Elasticsearch)

Elasticsearch требует высокого лимита vm.max_map_count. Проверьте и установите:

$ sysctl vm.max_map_count
$ 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

Шаг 4 — Установка Mastodon (структура директорий, Docker Compose и env)

Создайте каталоги и установите права владельца для необходимых директорий:

$ sudo mkdir -p /opt/mastodon/database/{postgresql,pgbackups,redis,elasticsearch}
$ sudo mkdir -p /opt/mastodon/web/{public,system}
$ sudo mkdir -p /opt/mastodon/branding
$ sudo chown 991:991 /opt/mastodon/web/{public,system}
$ sudo chown 1000 /opt/mastodon/database/elasticsearch
$ sudo chown 70:70 /opt/mastodon/database/pgbackups
$ cd /opt/mastodon
$ sudo touch application.env database.env
$ sudo nano docker-compose.yml

Вставьте в docker-compose.yml конфигурацию контейнеров (PostgreSQL, Redis, Elasticsearch, website, shell, streaming, sidekiq), как в оригинале. Пример файла: см. ниже.

(Содержимое docker-compose.yml сохранено в исходном руководстве — вставьте без изменений, при необходимости обновите теги образов.)

Важные примечания по docker-compose.yml

  • Убедитесь, что шаблон volumes указывает на реальные каталоги под /opt/mastodon.
  • Тег образа tootsuite/mastodon:v4.0.2 — проверьте релизы Mastodon и обновляйте версию по мере необходимости.
  • Elasticsearch в контейнере требует настройки ulimits (memlock/no-file) и локального порта 9200, проброшенного на 127.0.0.1:9200.

Генерация секретов и VAPID-ключей

Сгенерируйте секреты для приложения (SECRET_KEY_BASE, OTP_SECRET) и VAPID-ключи (для push-уведомлений):

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

Или используйте openssl:

$ openssl rand -hex 64
$ openssl rand -hex 15

Сохраните значения в файле application.env и database.env. Примерные значения и структура указаны в руководстве; заменяйте их на безопасные уникальные ключи.


Конфигурация application.env и database.env

Откройте application.env и database.env и внесите ваши значения: домен (LOCAL_DOMAIN), параметры SMTP (или удалите блок, если почта не нужна), секреты и значения для PostgreSQL/Elasticsearch/Redis. Не храните секреты в общедоступных репозиториях.

Пример (фрагмент):

RAILS_ENV=production
NODE_ENV=production
LOCAL_DOMAIN=mastodon.example.com
WEB_CONCURRENCY=2
MAX_THREADS=5
DEFAULT_LOCALE=en
SMTP_SERVER=email-smtp.us-west-2.amazonaws.com
SMTP_PORT=587
SMTP_LOGIN=AES_USER
SMTP_PASSWORD=AES_PWD
# secrets
SECRET_KEY_BASE=<ваш-секрет>
OTP_SECRET=<ваш-секрет>
VAPID_PRIVATE_KEY=
VAPID_PUBLIC_KEY=

И database.env с параметрами для Postgres, Elasticsearch и Redis.


Подготовка статических файлов и инициализация БД

Скопируйте статические файлы для Nginx и поднимите слои данных:

$ docker compose run --rm shell bash -c "cp -r /opt/mastodon/public/* /static/"
$ docker compose up -d postgresql redis redis-volatile
$ watch docker compose ps

Когда контейнеры будут в состоянии running (healthy), выполните инициализацию базы:

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

Шаг 5 — Установка Nginx

Добавьте официальный репозиторий Nginx, установите и запустите nginx:

$ 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 arch=amd64] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
  | sudo tee /etc/apt/sources.list.d/nginx.list
$ sudo apt update
$ sudo apt install nginx
$ sudo systemctl start nginx
$ sudo systemctl status nginx

Проверьте версию nginx через nginx -v.


Шаг 6 — SSL: Certbot и сертификаты

Рекомендуется использовать Certbot через snap для последних версий:

$ sudo snap install core
$ sudo snap refresh core
$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d mastodon.example.com
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
$ sudo certbot renew --dry-run

Certbot сохранит сертификаты в /etc/letsencrypt/live/mastodon.example.com.

Примечание: используйте реальный e-mail для восстановления доступа к сертификатам.


Шаг 7 — Конфигурация Nginx для Mastodon

Добавьте server_names_hash_bucket_size в /etc/nginx/nginx.conf перед include и создайте файл /etc/nginx/conf.d/mastodon.conf с конфигурацией обратного прокси, кеширования и статических ресурсов. В ключевых строках укажите пути к сертификатам Let’s Encrypt и корню сайта (/opt/mastodon/web/public).

Фрагмент конфигурации (важные параметры):

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;
  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;
  root /opt/mastodon/web/public;
  client_max_body_size 80m;
  location / { try_files $uri @proxy; }
  location @proxy { proxy_pass http://backend; }
  location /api/v1/streaming { proxy_pass http://streaming; }
}

Проверьте конфигурацию и перезапустите nginx:

$ sudo nginx -t
$ sudo systemctl restart nginx

Шаг 8 — Запуск Mastodon и служебные утилиты

tootctl на хосте

Создайте /usr/local/bin/tootctl, чтобы вызывать tootctl внутри контейнера:

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

Дайте файл executable: sudo chmod +x /usr/local/bin/tootctl

Сервис systemd для 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

Инициализация поиска (Elasticsearch)

Mastodon использует Elasticsearch для полнотекстового поиска. Создайте хотя бы одну запись (toot), затем выполните:

$ tootctl search deploy

Если вы столкнулись с ошибкой связанной с ruby-progressbar (ProgressBar::InvalidProgressError), временное решение — отредактировать файл внутри контейнера:

$ docker exec -it mastodon-website-1 /bin/bash
# внутри контейнера
$ sed -E '/progress.total = /d' -i lib/mastodon/search_cli.rb
$ exit
$ tootctl search deploy

Это известная проблема; следите за сообщениями в релизах Mastodon.


Дополнительные вспомогательные службы (таймеры для обслуживания)

Создайте systemd-сервисы и таймеры для периодического удаления медиа и карточек предпросмотра (preview cards). Примеры сервисов и таймеров приведены в руководстве: mastodon-media-remove.service, mastodon-preview_cards-remove.service и соответствующие .timer файлы. Не забудьте выполнить:

$ sudo systemctl daemon-reload
$ sudo systemctl enable --now mastodon-preview_cards-remove.timer mastodon-media-remove.timer
$ systemctl list-timers

Доступ к интерфейсам мониторинга

Для PgHero включите расширение pg_stat_statements в postgresql.conf:

shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all

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

$ sudo systemctl restart mastodon.service

Отладка — что проверить, если сайт не загружается

  • Логи Docker контейнеров:
$ docker logs 
  • Состояние контейнеров:
$ docker compose ps
  • Nginx: sudo nginx -t и sudo systemctl status nginx
  • Certbot: sudo certbot renew –dry-run
  • Проверить, что DNS A/AAAA запись указывает на ваш сервер
  • Проверить, что firewall/ufw не блокирует порты

Добавьте сюда правило: при ошибках 5xx сначала смотрите логи website и sidekiq, затем nginx.


Шаг 10 — Резервное копирование (Restic на S3)

Создайте список файлов для резервных копий (/opt/mastodon/backup-files), установите restic и настройте резервное хранилище S3. Пример создания и планирования бэкапов приведён в руководстве. Основные шаги:

$ 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

Пример скрипта /opt/mastodon/mastodon-backup сохраняет дамп PostgreSQL, вызывает restic для бэкапа и prunes по политике хранения.

Создайте systemd unit и timer для регулярных бэкапов (почасовой в примере).


Шаг 11 — Обновление Mastodon

Стандартный порядок обновления:

$ 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

Перед обновлением всегда проверяйте CHANGELOG/RELEASE NOTES Mastodon на предмет специальных шагов по миграции между версиями.


Безопасность и жёсткие рекомендации (production)

  • Используйте реестр секретов (Vault, SOPS, облачные секреты) вместо хранения ключей в plaintext.
  • Ограничьте доступ к серверу по SSH ключам; отключите вход по паролю.
  • Настройте автоматические обновления безопасности ОС либо используйте управляемые образы с поддержкой.
  • Регулярно выполняйте бэкапы БД и файлов, тестируйте процедуру восстановления.
  • Минимизируйте доступ к портам Elasticsearch извне — держите его доступным только локально (127.0.0.1).
  • Используйте fail2ban или аналог для защиты от брутфорс-атак.
  • Настройте мониторинг и оповещения (CPU, memory, диск, контейнеры, доступность веба).

SSL и HSTS

  • HSTS включён в конфигурации Nginx. Подумайте о включении preload только после тщательной проверки.
  • OCSP Stapling включён — проверяйте регулярные обновления сертификатов.

Жёсткая политика контейнеров

  • Подумайте об ограничении ресурсов Docker (memory/CPU) и использовании read-only корней для ненужных контейнеров.

Примечания по приватности и соответствию (GDPR)

  • Mastodon хранит IP-адреса и другой мета-контент. В файле application.env можно настроить IP_RETENTION_PERIOD (в секундах). Установите значение, соответствующее вашей политике конфиденциальности.
  • Проинформируйте пользователей об обработке персональных данных в правилах сервера и в настройках «Site settings».
  • Реализуйте процессы удаления данных по запросу пользователя (Data Subject Access Request). Технически это может включать удаление аккаунта и его связанного контента.
  • Хранение резервных копий: защищайте хранилище (S3) и шифруйте копии (restic шифрует данные по умолчанию).

Важно: для юридических советов по GDPR привлеките профильного юриста.


Runbook: если сайт упал — быстрый план действий

  1. Проверить доступность сервера (ping, SSH).
  2. Проверить статус systemd сервисов nginx/mastodon/docker.
  3. Просмотреть логи nginx и контейнеров:
    • sudo journalctl -u nginx -n 200
    • docker logs mastodon-website-1
  4. Если контейнеры не запущены: sudo systemctl restart mastodon.service; проверьте docker compose ps.
  5. При проблемах с БД — проверить свободное место и статус postgresql контейнера.
  6. При ошибках SSL — проверить /etc/letsencrypt и выполнить certbot renew –dry-run.
  7. Если необходимо восстановление: остановить Mastodon, восстановить БД из restic или из дампа, убедиться в соответствии версий.

Ролевые чек-листы (кто за что отвечает)

Администратор (операционный):

  • Настроить DNS и базовую сеть.
  • Проверить сертификаты и брандмауэр.
  • Настроить автоматические бэкапы и таймеры.
  • Обновлять ОС и Docker.

DevOps-инженер:

  • Подготовить docker-compose.yml и CI/CD для обновлений.
  • Настроить мониторинг и алёрты.
  • Тестировать процедуру восстановления из бэкапа.

Контент-модератор / Сайт-менеджер:

  • Настроить правила сервера и контактную информацию в разделе Site settings.
  • Мониторить Sidekiq на предмет зависших задач.

Полезные сценарии тестирования и критерии приёмки

Критерии приёмки (минимум):

  • Веб-интерфейс доступен по HTTPS и отображается корректно.
  • Пользователь может зарегистрироваться и авторизоваться.
  • Создание тоота отображается в ленте и сохраняется в БД.
  • Поиск работает (Elasticsearch проиндексировал хотя бы один тоот).
  • Регулярный бэкап выполняется и его можно монтировать/просмотреть.

Тест-кейсы:

  • Создать аккаунт, подтвердить e-mail (если используется) и сделать тоот.
  • Перезагрузить сервер и убедиться, что сервисы автоматически поднимаются.
  • Выполнить restore: восстановить дамп БД в изолированном окружении и проверить целостность.

Альтернативные подходы к развертыванию

  1. Сборка Mastodon из исходников (без Docker): больший контроль над окружением, но сложнее обновлять и поддерживать.
  2. Managed Mastodon хостинг (платные провайдеры): быстрее запустить, но меньше контроля и возможны ограничения по кастомизации.
  3. Kubernetes-ориентированное развертывание: для больших инстансов и команд, требующих масштабирования и сложного управления.

Рекомендация: Docker Compose — оптимальный баланс простоты и контроля для небольших и средних инстансов.


Совместимость и миграционные заметки

  • Проверяйте совместимость версий PostgreSQL, Redis и Elasticsearch с версией Mastodon, указанной в RELEASE NOTES.
  • Elasticsearch 7.x требует соответствующих Java-опций (ES_JAVA_OPTS). При обновлении ES следите за изменениями мажорных версий.
  • Перед миграцией выполняйте тестовый прогон миграций на копии БД.

Решение: когда Docker — не лучший выбор (галерея крайних случаев)

  • Очень высокая нагрузка с тысячами одновременно подключённых пользователей в веб-реальном времени: возможно, имеет смысл перейти на Kubernetes для лучшего оркестрования.
  • Строгие требования к уровню безопасности и аудиту в организации: может потребоваться изоляция на уровне хостов и продвинутая интеграция с IAM.

Небольшая методология обновления (минимальная последовательность)

  1. Прочитать RELEASE NOTES Mastodon для целевой версии.
  2. На тестовом сервере выполнить полное обновление и миграции.
  3. Выполнить бэкап продакшн-данных перед обновлением.
  4. Применить обновление на продакшне в окно техобслуживания.
  5. Проверить логи и мониторинг, откатить при критических ошибках.

Быстрый чек-лист перед открытием сервера пользователям

  • SSL корректно установлен и renew проходит успешно
  • Политики конфиденциальности и правила сервера описаны в Site settings
  • Бэкапы настроены и протестированы
  • Логи и мониторинг (Sidekiq, PgHero) доступны и проверены
  • Параметры безопасности (SSH, fail2ban, firewall) настроены

Краткая инструкция по восстановлению из бэкапа (runbook)

  1. Остановить Mastodon: sudo systemctl stop mastodon.service
  2. Восстановить дамп PostgreSQL из архива:
$ restic -r s3:https://$SERVER:$PORT/mybucket restore  --target /tmp/mastodon-restore
# затем внутри контейнера/данных восстановить dump.sql.gz
  1. Восстановить файлы /opt/mastodon/web/system и /etc/letsencrypt, если нужно.
  2. Запустить сервис: sudo systemctl start mastodon.service
  3. Проверить логи и работоспособность.

Decision tree: выбрать способ развертывания

flowchart TD
  A[Нужен быстрый запуск] -->|Да| B[Docker Compose]
  A -->|Нет| C[Оценить требования]
  C --> D{Требуется масштабирование?}
  D -->|Да| E[Kubernetes]
  D -->|Нет| F[Сборка из исходников]
  B --> G[Подходит для небольших/средних инстансов]
  E --> H[Подходит для больших инстансов и кластеров]
  F --> I[Полный контроль, больше работы]

Часто задаваемые вопросы (FAQ)

Q: Можно ли использовать другой почтовый сервис, помимо Amazon SES?
A: Да — Mailgun, SendGrid, SparkPost и др. поддерживаются. Просто укажите их SMTP-параметры в application.env.

Q: Нужно ли выставлять Elasticsearch на публичный интерфейс?
A: Нет. Для безопасности держите Elasticsearch доступным только на localhost/127.0.0.1 и проксируйте через nginx, если нужно.

Q: Как часто нужно делать бэкап?
A: В продакшне — минимум один раз в сутки, критичные инстансы — чаще (почасовой). Политика зависит от допустимой потери данных.


Визуальные примеры интерфейса

Превью Mastodon: главная страница

Страница ленты Mastodon с примером

Панель администратора Mastodon

Информация о пользователе в админке

Sidekiq — монитор процессов Mastodon

PgHero — метрики базы данных Mastodon

Пример статистики запросов в PgHero

Проверка медленных запросов


Резюме

  • Docker Compose обеспечивает быстрый и повторяемый путь развёртывания Mastodon на Ubuntu 22.04.
  • Обязательно настройте SSL, бэкапы и мониторинг до запуска публичных регистраций.
  • Тестируйте миграции в изолированном окружении и регулярно обновляйте образы и зависимости.

В случае вопросов — опишите проблему, приложите логи контейнера и конфигурации, и сообщество либо ваш инженер смогут помочь быстрее.


Социальная карточка (предложение)

OG title: Mastodon на Ubuntu 22.04 с Docker — пошаговое руководство

OG description: Разверните Mastodon на Ubuntu 22.04 через Docker: настройка, SSL, Nginx, бэкап и поддержка в продакшне.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Автообновление контейнеров с Podman
DevOps

Автообновление контейнеров с Podman

Ошибка system cannot find python.exe — как исправить
ошибки

Ошибка system cannot find python.exe — как исправить

Создать подпись в MS Outlook быстро
Email

Создать подпись в MS Outlook быстро

OpenSSH в Windows: встроенный SSH‑клиент
Системное администрирование

OpenSSH в Windows: встроенный SSH‑клиент

Не удаётся войти в Power BI Desktop — решения
Техническая поддержка

Не удаётся войти в Power BI Desktop — решения

Создать фальшивую стену Facebook: инструменты и шаги
соцсети

Создать фальшивую стену Facebook: инструменты и шаги