223 lines
15 KiB
Markdown
223 lines
15 KiB
Markdown
# Инструкция по развертыванию HAN Chat в production-like окружении
|
|
|
|
Это исполняемый чек-лист для контура на одной виртуальной машине. PostgreSQL и S3
|
|
используются как внешние управляемые сервисы. Во время развертывания запрещено
|
|
использовать `docker compose down -v`, откат миграций Alembic и изменяемые теги образов.
|
|
|
|
Подробная пошаговая инструкция для первого запуска находится в
|
|
`deployment/DEPLOYMENT_GUIDE.ru.md`.
|
|
|
|
## Этап 0 — решения и зоны ответственности
|
|
|
|
- [ ] Зафиксированы SHA/дайджесты релиза, окно обслуживания, дежурный и ответственный за откат.
|
|
- [ ] Согласованы RPO/RTO; начальные цели: RPO PostgreSQL не более 15 минут и RTO не более 4 часов.
|
|
- [ ] Выбран удаленный OTLP-бэкенд либо принято ограничение на использование только отладочного контура.
|
|
- [ ] Явно приняты риски mock OTP, заглушки Safety и заглушки bitrix-sync.
|
|
|
|
## Этап 1 — VPC, DNS и группы безопасности
|
|
|
|
- [ ] Управляемый PostgreSQL имеет только приватную точку доступа и принимает трафик от группы безопасности VM.
|
|
- [ ] Из интернета доступны только TCP-порты VM 80/443; SSH ограничен VPN или CIDR администраторов.
|
|
- [ ] Порты 6379, 4317/4318, 8000, 8080 и 9000 закрыты для внешнего доступа.
|
|
- [ ] DNS-запись `A` для `PUBLIC_HOST` указывает на VM; исходящий HTTPS доступен.
|
|
|
|
## Этап 2 — защита виртуальной машины
|
|
|
|
На новой Ubuntu 24.04 можно выполнить подготовительный скрипт:
|
|
|
|
```sh
|
|
sudo deployment/scripts/setup-vm.sh
|
|
```
|
|
|
|
Перед включением `HARDEN_SSH=true` обязательно проверьте вход по ключу в отдельной
|
|
SSH-сессии. Параметры запуска и безопасные значения по умолчанию описаны в начале скрипта.
|
|
|
|
- [ ] Установлена Ubuntu 24.04; работают NTP, автоматические обновления безопасности и оповещения о заполнении диска.
|
|
- [ ] Вход учетной записью развертывания по ключу проверен во второй сессии; вход root и SSH по паролю отключены.
|
|
- [ ] Правила UFW/облачной группы безопасности и политика `DOCKER-USER` сохраняются после перезагрузки.
|
|
- [ ] Docker Engine и Compose поддерживают `include` и полную форму `env_file`.
|
|
|
|
## Этап 3 — управляемый PostgreSQL
|
|
|
|
- [ ] Включены ежедневные резервные копии, PITR, защита от удаления, шифрование и оповещения.
|
|
- [ ] CA-сертификат провайдера установлен по пути `PG_CA_HOST_PATH`; все DSN используют `verify-full`.
|
|
- [ ] Для схем `han_app`, `bitrix_local`, `bitrix_sync`, `message_safety`, `keycloak`
|
|
созданы отдельные роли миграций и выполнения; запрет лишних прав проверен тестами.
|
|
- [ ] Миграции проверены на пустой БД и на клоне БД предыдущего релиза.
|
|
|
|
## Этап 4 — Selectel S3
|
|
|
|
- [ ] Бакеты карантина, вложений и документов закрыты от публичного доступа и зашифрованы.
|
|
- [ ] Права API ограничены префиксами; учетные данные Safety имеют доступ к карантину только на чтение.
|
|
- [ ] CORS бакетов разрешает только точный HTTPS-origin браузера и необходимые заголовки PUT.
|
|
- [ ] Срок хранения карантина превышает время Safety polling/recovery; политика хранения данных согласована.
|
|
|
|
## Этап 5 — неизменяемый релиз
|
|
|
|
- [ ] Репозиторий переключен на утвержденный SHA в detached-режиме; рабочее дерево чистое.
|
|
- [ ] Образы сервисов неизменяемы и просканированы; нерешенных критических и высоких уязвимостей нет.
|
|
- [ ] Корневой `docker-compose.yml` является единственной точкой запуска.
|
|
|
|
## Этап 6 — окружение и секреты
|
|
|
|
```sh
|
|
umask 077
|
|
cp .env.example .env
|
|
chmod 600 .env
|
|
# Замените заглушки через защищенный редактор или менеджер секретов.
|
|
./scripts/validate-env .env
|
|
docker compose --env-file .env config --quiet
|
|
```
|
|
|
|
- [ ] Парные токены совпадают, PostgreSQL проверяет TLS, публичные URL используют HTTPS.
|
|
- [ ] Риск mock OTP принят; все секреты уникальны и содержат не менее 128 бит энтропии.
|
|
- [ ] Установлено `FRONTEND_DEV_PROXY_ENABLED=false`; таймауты Safety и nginx согласованы.
|
|
|
|
## Этап 7 — образы и статический frontend
|
|
|
|
```sh
|
|
docker compose --env-file .env pull
|
|
docker compose --env-file .env build --pull frontend-static nginx redis
|
|
docker compose --env-file .env run --rm frontend-static
|
|
```
|
|
|
|
- [ ] Экспорт frontend проверен и просканирован, затем скопирован сервисом `frontend-static` в именованный volume.
|
|
- [ ] Артефакты сборки не содержат секретов и непредусмотренных source map.
|
|
- [ ] На диске VM остается не менее 30% свободного места.
|
|
|
|
## Этап 8 — топология
|
|
|
|
```sh
|
|
docker compose --env-file .env config --services
|
|
python3 -m unittest discover -s tests -v
|
|
```
|
|
|
|
- [ ] Только nginx публикует `80:80` и `443:443`; сервиса PostgreSQL в Compose нет.
|
|
- [ ] Присутствуют volumes Redis AOF/RDB/ACL и постоянной очереди OTEL.
|
|
- [ ] Сети `backend` и `observability` являются внутренними.
|
|
|
|
## Этап 9 — первоначальная настройка ACME/TLS
|
|
|
|
Установите `NGINX_TLS_ENABLED=false` только для команды первоначального запуска:
|
|
|
|
```sh
|
|
NGINX_TLS_ENABLED=false docker compose --env-file .env up -d nginx
|
|
docker compose --profile certbot run --rm certbot certonly \
|
|
--webroot -w /var/www/certbot -d "$PUBLIC_HOST" \
|
|
--cert-name "$PUBLIC_HOST" --email "$ACME_EMAIL" \
|
|
--agree-tos --no-eff-email --non-interactive
|
|
docker compose --env-file .env up -d --force-recreate nginx
|
|
docker compose exec -T nginx nginx -t -c /tmp/nginx.conf
|
|
```
|
|
|
|
Сначала выполните проверку с параметром Certbot `--staging`. Установите systemd-таймер,
|
|
запускающий `deployment/scripts/ssl-renew.sh` дважды в сутки, и проверьте
|
|
`certbot renew --dry-run`. Включайте HSTS только после проверки цепочки сертификатов,
|
|
имени хоста, перенаправления и поддержки TLS 1.2/1.3.
|
|
|
|
## Этап 10 — миграции и начальные данные
|
|
|
|
Создайте у провайдера точку восстановления PITR, затем выполните:
|
|
|
|
```sh
|
|
PITR_MARKER_CONFIRMED=true deployment/scripts/migrate.sh
|
|
deployment/scripts/seed.sh
|
|
```
|
|
|
|
- [ ] Активны ожидаемые ревизии Alembic; runtime-пользователи не выполняли DDL.
|
|
- [ ] Повторный seed завершается успешно; обязательные настройки не содержат секретов.
|
|
- [ ] Схема остается обратно совместимой с образами предыдущего релиза.
|
|
|
|
## Этап 11 — Keycloak
|
|
|
|
```sh
|
|
docker compose up -d keycloak
|
|
docker compose ps keycloak
|
|
```
|
|
|
|
- [ ] Issuer discovery/JWKS точно совпадает с публичным HTTPS URL `/auth`.
|
|
- [ ] Frontend-клиент является публичным PKCE S256; implicit, password и social flows отключены.
|
|
- [ ] Неверный или повторно использованный OTP и превышение лимитов безопасно отклоняются; settings bridge работает fail-closed.
|
|
- [ ] Временный администратор удален либо его пароль изменен; для именного администратора включена MFA.
|
|
|
|
## Этап 12 — последовательный запуск и готовность
|
|
|
|
```sh
|
|
docker compose up -d redis
|
|
docker compose up -d keycloak otel-collector
|
|
docker compose up -d message-safety
|
|
docker compose up -d api-backend
|
|
docker compose up -d bitrix-local-app bitrix-sync
|
|
docker compose up -d nginx
|
|
docker compose ps
|
|
```
|
|
|
|
- [ ] Нет циклических перезапусков и OOM; критические readiness-проверки успешны.
|
|
- [ ] Сохраняется только документированная деградация: Bitrix не установлен и bitrix-sync работает как заглушка.
|
|
- [ ] Внешний запрос `/internal/*` возвращает 404; OTEL принимает телеметрию.
|
|
|
|
## Этап 13 — Bitrix24
|
|
|
|
- [ ] URL установки, обработчика и placement используют точные публичные HTTPS-пути.
|
|
- [ ] Коннектор `han_mobile_app` активен в Открытой линии 8; события привязаны однократно.
|
|
- [ ] OAuth зашифрован; callback-, application- и service-токены не попадают в логи.
|
|
- [ ] Исходящие сообщения и ответы оператора идемпотентны; внутренний статус не опубликован наружу.
|
|
|
|
## Этап 14 — smoke- и E2E-тесты
|
|
|
|
```sh
|
|
deployment/scripts/smoke.sh
|
|
```
|
|
|
|
- [ ] Успешны сценарии гостя, OTP/PKCE/bootstrap/session, обновления токена и выхода.
|
|
- [ ] Проверены Safety allow/deny/pending/timeout и один параллельный медленный poll.
|
|
- [ ] Проверены карантин, перенос и удаление файлов, скачивание только владельцем и аудит.
|
|
- [ ] Проверены переподключение WS с REST-сверкой, 404 при обращении к чужому ресурсу, идемпотентность и 429.
|
|
- [ ] Логи не содержат PII, текстов сообщений, токенов и query-параметров presigned URL.
|
|
|
|
## Этап 15 — наблюдаемость
|
|
|
|
- [ ] Известный request ID связывает трассировку nginx, API и downstream-сервисов; UX ID не используется как label.
|
|
- [ ] Все три сигнала поступают в выбранный бэкенд; SLO-запросы и оповещения проверены.
|
|
- [ ] При недоступности удаленного сервиса ограниченная постоянная очередь заполняется и опустошается без остановки бизнес-функций.
|
|
- [ ] Тестовые секреты и PII отсутствуют; проверены метрики перезапуска, потерь, отказов и очереди Collector.
|
|
|
|
Только для локальной приемки запустите отладочный Collector с удалением чувствительных данных:
|
|
`docker compose --profile observability-local up -d otel-collector-local`.
|
|
|
|
## Этап 16 — открытие трафика
|
|
|
|
- [ ] Этапы 0–15 подписаны; имеются свежие подтверждения backup/PITR и предыдущие образы.
|
|
- [ ] HSTS включен; дайджесты релиза, версии схем и realm зафиксированы.
|
|
- [ ] Активных инцидентов нет; дежурный и владелец продукта приняли ограничения заглушек.
|
|
- [ ] В течение 60 минут контролируются 5xx, auth, доставка, БД, Redis, OOM, очередь OTEL и Bitrix.
|
|
|
|
## Резервное копирование и восстановление
|
|
|
|
Основным механизмом являются backup/PITR провайдера. Дополнительный проверенный логический дамп:
|
|
|
|
```sh
|
|
PG_BACKUP_DSN='postgresql://...?...sslmode=verify-full&sslrootcert=...' \
|
|
deployment/scripts/backup.sh /opt/han-chat/backups
|
|
```
|
|
|
|
Ежеквартально восстанавливайте PostgreSQL и S3 в изолированной VPC, развертывайте те же
|
|
дайджесты образов, не направляйте туда production DNS и callbacks Bitrix, выполняйте
|
|
smoke-тесты и фиксируйте фактические RPO/RTO. Redis можно восстановить пустым:
|
|
его AOF/RDB не является резервной копией бизнес-данных.
|
|
|
|
## Откат
|
|
|
|
Откатывайтесь только на образы, совместимые с текущей схемой:
|
|
|
|
```sh
|
|
SCHEMA_BACKWARD_COMPATIBLE_CONFIRMED=true \
|
|
deployment/scripts/rollback.sh /secure/path/previous-release.env
|
|
ENV_FILE=/secure/path/previous-release.env deployment/scripts/smoke.sh
|
|
```
|
|
|
|
Никогда не выполняйте downgrade Alembic. После обратно несовместимой миграции используйте
|
|
исправление вперед либо согласованный PITR с восстановлением S3 и сверкой Bitrix во время
|
|
технического обслуживания. Всегда проверяйте outbox, inbox и recovery, чтобы сообщение
|
|
с неопределенным статусом не было отправлено повторно.
|