Files
rf4-spotter/deploy
ik bb61d21dd6
CI / backend-and-migrations (push) Canceled after 0s
CI / astro-build (push) Canceled after 0s
CI / compose-e2e (push) Canceled after 0s
sync
2026-09-08 21:07:07 +07:00
..
2026-09-08 21:07:07 +07:00

Развёртывание открытой альфы rf4spotter.ru

Production-контур рассчитан на один Linux-сервер с Docker Compose. Наружу публикуются только Caddy 80/443; PostgreSQL, FastAPI и MinIO не имеют host-портов. Административные страницы защищены одновременно Caddy Basic Auth и API bearer token.

Текущее состояние публичных DNS/TLS и незакрытые инфраструктурные действия ведутся в docs/deployment-status.md.

1. DNS и сервер

Создайте A-записи rf4spotter.ru и files.rf4spotter.ru на публичный IPv4 сервера. При наличии рабочего IPv6 добавьте AAAA для обоих имён. До запуска убедитесь, что извне доступны TCP 80/443 и UDP 443; SSH ограничьте своим IP или VPN. Порты 4321, 8000, 9000, 9001 и 5432 открывать нельзя.

Минимум для открытой альфы: 2 vCPU, 4 ГБ RAM и 40 ГБ SSD. Рекомендуется 4 vCPU, 8 ГБ RAM и отдельное внешнее место для резервных копий.

2. Секреты

На сервере:

cp .env.production.example .env.production
chmod 600 .env.production
openssl rand -base64 36  # отдельные значения для БД, ADMIN_TOKEN, RATE_LIMIT_SECRET, MinIO root и S3 app
docker run --rm caddy:2.10.2-alpine caddy hash-password --plaintext 'ОТДЕЛЬНЫЙ ADMIN-ПАРОЛЬ'

Заполните .env.production. Хеш Caddy содержит символы $, поэтому значение ADMIN_BASIC_PASSWORD_HASH в env-файле заключите в одинарные кавычки. MINIO_ROOT_* и S3_* обязаны быть разными: init-контейнер проверяет это, API получает только application credentials. Если пароль PostgreSQL содержит специальные символы, в DATABASE_URL нужна URL-кодированная форма того же пароля. .env.production нельзя коммитить или пересылать вместе с логами.

3. Проверка и первый запуск

Перед первым запуском проверьте секреты и итоговую Compose-конфигурацию, не выводя значения в лог:

./deploy/preflight.sh

Перед сборкой запишите текущий git rev-parse --short HEAD в APP_REVISION файла .env.production, чтобы /ready однозначно показывал развёрнутый commit.

PUBLIC_CACHE_SECONDS задаёт короткий in-process кэш публичного агрегата активности (по умолчанию 20 секунд). Не увеличивайте его без повторной проверки свежести после публикации.

docker compose --env-file .env.production -f compose.production.yaml config --quiet
docker compose --env-file .env.production -f compose.production.yaml build
docker compose --env-file .env.production -f compose.production.yaml up -d
docker compose --env-file .env.production -f compose.production.yaml ps
curl -fsS https://rf4spotter.ru/health
curl -fsS https://rf4spotter.ru/ready

Безопасный диагностический снимок для администратора:

curl -fsS -H "Authorization: Bearer $ADMIN_TOKEN" -o rf4spotter-diagnostics.json https://rf4spotter.ru/api/v1/admin/diagnostics

После обновления DNS и получения сертификатов выполните внешний этап той же проверки:

./deploy/preflight.sh --online

До запуска на сервере можно воспроизвести полный production bootstrap на пустых изолированных volumes. Скрипт собирает образы, применяет миграции, проверяет отсутствие демо-уловов, readiness и отправку заявки:

./deploy/test-production-bootstrap.sh

По умолчанию временно используются только loopback-порты 14321 и 18000; PostgreSQL и MinIO наружу не публикуются. Контур и volumes удаляются после проверки. Drill успешно пройден 6 сентября 2026 года.

API-контейнер перед стартом применяет Alembic-миграции и запускает идемпотентный seed. В production он добавляет только минимальные справочники и точки; демонстрационные уловы жёстко отключены настройкой SEED_DEMO_DATA=false.

Проверка TLS и маршрутизации:

curl -I https://rf4spotter.ru/
curl -I https://files.rf4spotter.ru/minio/health/live

MinIO health URL допустим для диагностики, но Console наружу не публикуется. Объекты доступны только по временным подписанным ссылкам.

4. Первичные данные

Официальный импорт запускается вручную после успешного readiness:

docker compose --env-file .env.production -f compose.production.yaml exec api python -m app.cli import-records

Автоматический scheduler не входит в production-файл. RF4MAP и RF4 Posts нельзя опрашивать чаще одного раза в 30 минут; до отдельной эксплуатационной задачи используйте только контролируемые ручные запуски и staging.

Официальный импорт защищён PostgreSQL advisory lock на комбинацию source/region/category. Параллельный admin-запрос получает 409, а scheduler записывает безопасный skip и не делает второй HTTP-запрос к источнику.

5. Обновление

git pull --ff-only
docker compose --env-file .env.production -f compose.production.yaml build
docker compose --env-file .env.production -f compose.production.yaml up -d
docker compose --env-file .env.production -f compose.production.yaml ps
curl -fsS https://rf4spotter.ru/ready

Перед обновлением со сменой схемы обязателен backup PostgreSQL. Не удаляйте volumes и не используйте down -v.

6. Резервное копирование и восстановление

Храните копии вне диска приложения. Скрипт создаёт PostgreSQL dump, архив MinIO и контрольные суммы в новом каталоге с UTC-временем:

./deploy/backup.sh /srv/rf4-backups

Восстановление заменяет содержимое PostgreSQL и MinIO данными из выбранной копии, временно останавливая API и web. Это намеренно защищённая подтверждением операция:

CONFIRM_RESTORE=rf4-spotter ./deploy/restore.sh /srv/rf4-backups/20260906T120000Z
curl -fsS https://rf4spotter.ru/ready

Репозиторий содержит изолированный drill, который создаёт отдельные Compose volumes, портит тестовые данные, восстанавливает их и сравнивает PostgreSQL и MinIO:

./deploy/test-backup-restore.sh

Drill успешно пройден 6 сентября 2026 года. На целевом сервере всё равно проведите учебное восстановление с реальной зашифрованной копией перед приглашением пользователей. Затем настройте ежедневный запуск backup.sh, выгрузку копий во внешнее хранилище и уведомление при ошибке; храните минимум 7 ежедневных и 4 еженедельных копии.

7. Ежедневное обслуживание

После успешного backup сначала проверьте план очистки, затем примените его:

docker compose --env-file .env.production -f compose.production.yaml exec -T api python -m app.cli cleanup-retention
docker compose --env-file .env.production -f compose.production.yaml exec -T api python -m app.cli cleanup-retention --apply

Сроки и состав данных описаны в docs/data-retention.md. Автоматизацию включайте только после проверки dry-run на рабочем наборе.

После ручной проверки установите ежедневный timer. maintenance.sh использует lock от параллельного запуска и применяет retention только после успешного backup:

sudo cp deploy/systemd/rf4spotter-maintenance.service /etc/systemd/system/
sudo cp deploy/systemd/rf4spotter-maintenance.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now rf4spotter-maintenance.timer
systemctl list-timers rf4spotter-maintenance.timer

Шаблон рассчитан на пользователя rf4spotter, каталог /opt/rf4-spotter и наличие flock из util-linux. Пользователь должен иметь доступ к Docker socket и каталогу BACKUP_ROOT. Результат каждого запуска хранится в systemd journal. Docker JSON-логи production-сервисов ограничены пятью файлами по 10 МБ на контейнер.

8. Мониторинг

После настройки DNS, TLS и первого backup выполните:

./deploy/monitor.sh

Проверка контролирует контейнеры, /ready, диск, объём PostgreSQL/MinIO, свежесть backup и срок TLS. Установка systemd timer, пороги и порядок реакции описаны в docs/production-monitoring.md. До подключения реального канала уведомлений одного журнала systemd недостаточно.

9. Что ещё блокирует публичное открытие альфы

  • подключение уведомлений о сбоях мониторинга;
  • проверка DNS/TLS и полного запуска на целевом сервере;
  • внешнее зашифрованное хранилище резервных копий.
  • действующие privacy@rf4spotter.ru и abuse@rf4spotter.ru, публичные правила и privacy notice;
  • проверка rate limit и очереди модерации под ожидаемой публичной нагрузкой.

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