# GoToSocial Deploy — Delta Spec ## ADDED Requirements ### Requirement: Инстанс GoToSocial работает в Docker на bigbox - **MUST**: Сервис GoToSocial запускается как Docker-контейнер из `/opt/gotosocial` через `docker compose` - **MUST**: Используется образ с фиксированным тегом последнего стабильного релиза (например `superseriousbusiness/gotosocial:v0.22.1`) - **MUST**: Контейнер имеет volume для данных: `data/sqlite.db` (SQLite) и `data/storage` (медиа) - **MUST**: Приложение слушает порт внутри контейнера, проброшенный наружу (например `8080:8080`) - **SHOULD**: Рестарт контейнера настроен (`restart: unless-stopped`) #### Scenario: Контейнер запущен - GIVEN контейнер запущен, WHEN `docker ps`, THEN контейнер `gotosocial` в статусе Up - GIVEN сервис работает, WHEN `curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:/`, THEN HTTP 200 ### Requirement: Split-domain — host social.dedinit.ru, account-domain dedinit.ru - **MUST**: В `config.yaml`: `host: social.dedinit.ru`, `account-domain: dedinit.ru`, `protocol: https` - **MUST**: Не менять `host`/`account-domain` после первого запуска (необратимо) - **MUST**: На apex `dedinit.ru` (Jino) добавлены редиректы: - `/.well-known/webfinger` → `https://social.dedinit.ru/.well-known/webfinger` - `/.well-known/nodeinfo` → `https://social.dedinit.ru/.well-known/nodeinfo` - `/.well-known/host-meta` → `https://social.dedinit.ru/.well-known/host-meta` - **SHOULD**: Проверить редиректы после публикации на apex #### Scenario: Webfinger резолвится - GIVEN инстанс запущен, WHEN `curl -s -H 'Accept: application/json' 'https://social.dedinit.ru/.well-known/webfinger?resource=acct:estorozhenko@dedinit.ru'`, THEN JSON с actor - GIVEN apex настроен, WHEN `curl -s -o /dev/null -w '%{http_code}' -L 'https://dedinit.ru/.well-known/webfinger?resource=acct:estorozhenko@dedinit.ru'`, THEN 200 после редиректа ### Requirement: TLS через Caddy на vps02 - **MUST**: Caddy (vps02, host net) имеет блок `social.dedinit.ru { reverse_proxy 10.8.0.2: }` - **MUST**: Caddy выпускает Let's Encrypt сертификат для social.dedinit.ru автоматически - **MUST**: GtS доверяет прокси: в `config.yaml` `trusted-proxies` включает IP/подсеть Caddy (например `10.8.0.2`) - **SHOULD**: Header `Host` и `X-Forwarded-Proto` передаются в GtS #### Scenario: HTTPS работает - GIVEN Caddy настроен, WHEN `curl -s -o /dev/null -w '%{http_code}' https://social.dedinit.ru/`, THEN 200 - GIVEN сертификат, WHEN `echo | openssl s_client -connect social.dedinit.ru:443 2>/dev/null | openssl x509 -noout -dates`, THEN даты валидны ### Requirement: SMTP-отправка писем - **MUST**: `config.yaml` содержит SMTP: `smtp.jino.ru:587`, STARTTLS, логин `social@dedinit.ru` (пароль из `.env`) - **MUST**: Письма (подтверждение email, уведомления) отправляются через SMTP-сервер - **SHOULD**: Проверка отправки тестового письма #### Scenario: Отправка письма - GIVEN SMTP настроен, WHEN администратор инициирует отправку (например создание пользователя / тест), THEN письмо доставлено на указанный адрес - GIVEN неверный пароль SMTP, WHEN отправка, THEN в логах GtS ошибка аутентификации (не тихий fail) ### Requirement: Метрики Prometheus - **MUST**: В `config.yaml`: `metrics-enabled: true` - **MUST**: Переменные окружения `OTEL_METRICS_PRODUCERS=prometheus`, `OTEL_METRICS_EXPORTER=prometheus` - **MUST**: Эндпоинт `/metrics` отдаёт метрики в формате Prometheus (Go runtime, Gin HTTP, Bun DB) - **SHOULD**: Prometheus на bigbox скрейпит `127.0.0.1:/metrics` (добавлен job) #### Scenario: Эндпоинт метрик - GIVEN GtS запущен, WHEN `curl -s http://127.0.0.1:/metrics | head`, THEN вывод содержит `go_goroutines`, `gin_`, `bun_` префиксы - GIVEN Prometheus настроен, WHEN `curl http://127.0.0.1:9090/api/v1/targets`, THEN job `gotosocial` в статусе UP ### Requirement: Логи в JSON для сбора - **MUST**: `config.yaml`: `log-format: json` (для Promtail/Loki) - **SHOULD**: Promtail собирает docker-логи контейнера `gotosocial` (label `container=gotosocial` / job `gotosocial`) #### Scenario: Логи в JSON - GIVEN контейнер пишет логи, WHEN `docker logs gotosocial | head`, THEN строки в JSON-формате ## MODIFIED Requirements (нет)