# Развёртывание платформы Одна VM, systemd, бинари артефактами CI (`PLATFORM_DIRECTION.md` §3). Не Kubernetes: дети-`tmctl` живут часами и держат эксклюзивный лок на файлах книги на локальном диске — оркестратор, способный переселить под посреди прогона, этой нагрузке враждебен. ## Файлы - `tmplatformd.service` — юнит контрольной панели. Тело юнита проверено `systemd-analyze verify` (systemd 259) — exit 0, без замечаний. ⚠ Проверять надо с ПОДСТАВЛЕННЫМ существующим `ExecStart=`: дословно юнит даёт exit 1, потому что `verify` проверяет и наличие бинаря, а `/usr/local/bin/tmplatformd` на стенде нет. ⚠ **живого прогона под systemd не было** — на машине нет sudo, юнит не устанавливался. ## Откат релиза: не ниже версии 5 `goose down` до версии 4 и ниже НЕ РАБОТАЕТ на живой базе: down-путь `00005` восстанавливает `users_email_key` и `email NOT NULL`, а обе формы нарушают строки, которые пишет боевой код (неподтверждённая личность даёт `email = NULL`; один адрес законно принадлежит двум аккаунтам). Откат транзакционный, поэтому падение ничего не портит — но планировать откат ниже 5 нельзя, план отката — накатить вперёд. Разбор: `docs/STACK_DECISIONS.md` §8. ## Что юнит закрывает содержательно - **PD-13 (осиротевшие процессы движка).** Каждый `tmctl` живёт в cgroup ЭТОГО юнита, поэтому падение или рестарт платформы не оставляет прогон без присмотра. Обычную остановку делает супервизор (группа процессов, `internal/ingest/procgroup_unix.go`); cgroup — это ответ на случай, когда супервизора уже нет, чтобы попросить. - **`TimeoutStopSec=90`** больше, чем дренаж платформы (15 с) плюс grace движка (30 с). Меньше — и systemd прибьёт `tmctl` посреди остановки, оставив лок проекта. - **Секреты через `LoadCredential=`,** а не через окружение: переменная окружения видна в `/proc//environ` и наследуется каждым ребёнком-`tmctl`. Конфиг читает `*_FILE` первым. ## Установка (набросок, исполняется владельцем) ```sh useradd --system --home /srv/textmachine tmplatform install -D -m0755 tmplatformd /usr/local/bin/tmplatformd install -D -m0755 tmplatformctl /usr/local/bin/tmplatformctl install -d -m0700 -o root -g root /etc/tmplatform printf '%s' 'postgres://...' > /etc/tmplatform/dsn && chmod 0400 /etc/tmplatform/dsn printf '%s' '' > /etc/tmplatform/oidc_client_secret && chmod 0400 /etc/tmplatform/oidc_client_secret ``` `/etc/tmplatform/env` — несекретное окружение: ``` TM_PLATFORM_ADDR=127.0.0.1:8080 TM_PLATFORM_TRUSTED_ORIGINS=https://app.example.org TM_PLATFORM_OIDC_ISSUER=https://accounts.google.com TM_PLATFORM_OIDC_CLIENT_ID=... TM_PLATFORM_OIDC_REDIRECT_URL=https://app.example.org/auth/callback TM_PLATFORM_AFTER_LOGIN=/library TM_PLATFORM_SIGNUP_GRANT_USD=5 ``` Миграции выкатываются ОДИН раз, не каждой репликой: `TM_PLATFORM_MIGRATE=1 tmplatformd` разово либо отдельный шаг деплоя. `goose` держит advisory-лок, так что параллельный запуск не гонка, но и не норма. ## Чего здесь ещё нет TLS и домен (перед юнитом предполагается edge-прокси), ограничитель соединений на edge, ротация логов, бэкап Postgres. Всё это — работа с первым реальным деплоем, не раньше.