- Новый порядок этапов (D-026): фаза 1 — концепт на dev без внешних сервисов (1b сайт, 1c вход, 1d ключи, 1e счёт и демо-оплата, 1f демо-выдача, 1g продления, 1h рефералы); фаза 2 — Telegram; фаза 3 — ALTCHA, ЮKassa, почта, Twenty, Chatwoot, Umami, выдача через API и публичный запуск; фаза 4 — звёзды и эквайринги. - Решения: демо-оплата по списку IP (D-027), выдача ключей через адаптер manual/demo/api (D-028), страницы сайта из блоков Payload (D-029), пересборка через revalidatePath (D-030), RU-адрес у mass (D-031), счётчик свободных серверов (D-032), переводы на 5 языков в каждом этапе (D-033). - Тексты описывают работающий продукт; Вейликс — выделенный IP на общем сервере; Telegram поддержки — @veilix_support; сроки ответа не обещаем; VPN-серверы не ведут журналов. - Ссылки на этапы во всех документах, Q-12 решён (ЮKassa для RUB), R-19 (библиотеки для headless Chromium) сделано. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
15 KiB
15 KiB
09. Инфраструктура
1. Сервер (проверено 18–20.10.2026)
| Что | Значение |
|---|---|
| ОС | Ubuntu 26.04.1 LTS |
| Ресурсы | 4 vCPU, 7.7 ГБ RAM, 8 ГБ swap, 145 ГБ диска (занято 24 ГБ) |
| IP | 169.58.76.183 — сайты (PTR fr-ub2gs3.veilix.cc, прямая запись совпадает); 173.212.216.183 — основной, через него по умолчанию идёт исходящий трафик (PTR vmi3593751.contaboserver.net) |
| Установлено | Node 24.22, PostgreSQL 18.6, nginx 1.28 (модули geoip2 и brotli подключены), Redis 8, Postfix 3.10, OpenDKIM, certbot 4.0, Docker 29 (не используем), git |
| Нет | pnpm, база GeoLite2 (.mmdb), сертификаты TLS, geoipupdate |
| DNS | все 15 хостов проекта (вместе с umi.veilix.cc) указывают на 169.58.76.183; DNS-хостинг — Gcore |
2. Папки
/home/vx_dev/veilix_dev/ — dev (пользователь vx_dev): рабочая копия git, .env, media/
/home/vx_prod/veilix/ — prod (пользователь vx_prod), закрыто для остальных
releases/<дата-тег>/ — собранные релизы (храним 5 последних)
current -> releases/… — симлинк на работающий релиз
shared/.env — секреты prod
shared/media/ — загруженные файлы prod
/home/umami/umami/ — Umami (пользователь umami)
vx — личный пользователь администратора, к проекту отношения не имеет. Под vx_prod нет редактора и ИИ-агентов, VSCode Remote под vx_prod не подключаем (D-004). Домашние папки всех пользователей — 750, владелец — сам пользователь. Пустые папки /home/vx/veilix.app, /home/vx/my.veilix.app, /home/vx/tg.veilix.app проекту не нужны.
3. Процессы
- Каждый сервис — под своим пользователем ОС, как systemd user-юнит. Root один раз включает
loginctl enable-lingerдля vx_dev, vx_prod и umami, чтобы юниты работали без входа в систему. veilix-dev.service(vx_dev):pnpm devна 127.0.0.1:3100 из/home/vx_dev/veilix_dev, перезапуск при сбое. Файл юнита —ops/systemd/veilix-dev.serviceв репозитории, подключён черезsystemctl --user link.veilix.service(vx_prod):pnpm startна порту 3000 из/home/vx_prod/veilix/current,NODE_ENV=production, перезапуск всегда.umami.service(umami): Umami на порту 3300.- Фоновые задачи Payload выполняются внутри процессов приложения (02-architecture.md, раздел 7).
- Логи — journald, у каждого пользователя свои (
journalctl --user -u veilixпод vx_prod). Сессии Claude логи prod не видят: при разборе проблем prod их присылает пользователь. - Проверка живости —
/svc/health(с проверкой базы).
4. nginx
| Хосты | Куда | Доступ |
|---|---|---|
| veilix.app, veilixvpn.com, my.veilix.app, my.veilixvpn.com, tg.veilix.app, tg.veilixvpn.com | 127.0.0.1:3000 | открыт |
| plc.veilix.cc | 127.0.0.1:3000 | только разрешённые IP |
| dev.veilix.app, dev.my.veilix.app, dev.veilixvpn.com, dev.my.veilixvpn.com | 127.0.0.1:3100 | только разрешённые IP или пароль; X-Robots-Tag: noindex |
| dev.tg.veilix.app, dev.tg.veilixvpn.com | 127.0.0.1:3100 | открыт для Telegram; приложение пускает только разрешённые Telegram-аккаунты |
| dev.plc.veilix.cc | 127.0.0.1:3100 | только разрешённые IP |
| umi.veilix.cc | 127.0.0.1:3300 | только разрешённые IP |
- Слушает 169.58.76.183, порты 80 (редирект на HTTPS и проверка certbot) и 443. TLS 1.2 и 1.3, HTTP/2, HSTS.
- Сертификаты — certbot, проверка через HTTP.
- Сжатие — brotli и gzip.
- GeoIP: блок
geoip2в/etc/nginx/conf/ip.conf, база/var/lib/GeoIP/GeoLite2-Country.mmdbсauto_reload. Переменная$geoip_country_codeуходит приложению заголовкомX-Geo-Country; такой же заголовок от клиента nginx затирает. Старый модуль GeoIP v1 (modules-enabled/50-mod-http-geoip.conf) отключён: он занимает те же имена переменных, иnginx -tпадает с ошибкой «the duplicate "geoip_country_code" variable». - Заголовки к приложению — общий файл
/etc/nginx/snippets/veilix_proxy.conf(плюсmaps/upgrade.confдля WebSocket), его подключает каждыйlocationсproxy_pass:Host,X-Real-IPиX-Forwarded-For(оба —$remote_addr: nginx стоит первым, цепочку от клиента не принимаем),X-Forwarded-Proto,X-Geo-Country, заголовки WebSocket (нужны горячей перезагрузке dev).proxy_set_headerне наследуется вlocationсо своимиproxy_set_header, поэтому файл подключается в каждый такойlocation. - В
nginx.confподключаются толькоsites-enabled/*.conf: файлы сайтов должны заканчиваться на.conf. Сайты:sites-available/02_vx_veilix-prod.conf,02_vx_veilix-dev.conf,02_vx_plc-prod.conf,02_vx_plc-dev.conf. Сертификаты Let's Encrypt (certbot, проверка через nginx):veilix.app(6 prod-хостов брендов),dev.veilix.app(6 dev-хостов),plc.veilix.cc,dev.plc.veilix.cc. a. Доступ по IP — файлconf/ip_list_admin.confсо строкамиallow …;, вlocationпосле негоdeny all;. Подключается на хостах админки и dev, кромеdev.tg.*. b.dev.tg.*— отдельныйserverбез ограничения по IP, сX-Robots-Tag: noindex. c. На порту 80 —location / { return 301 https://$host$request_uri; }. Именно внутриlocation, а не на уровнеserver: так certbot при продлении может вставить свойlocationдля проверки домена. - Лимиты запросов (
limit_req) на эндпоинты входа и формы. - Для tg.* (этап 2a) разрешить показ во фрейме Telegram Web (
frame-ancestorsдля доменов telegram.org). - Пути трекера Umami на доменах брендов проксируются на 127.0.0.1:3300 (08-integrations.md, раздел 8).
- Конфигурацию готовит Claude текстом на согласование, применяет root.
5. PostgreSQL
- Базы
veilix_dev,veilix_prodиumami. Владелец каждой — роль с именем пользователя ОС:vx_dev,vx_prod,umami. - Вход по Unix-сокету с проверкой пользователя ОС: стандартное правило Ubuntu
local all all peerвpg_hba.confпускает пользователя ОС только под ролью с тем же именем. Паролей нет,pg_hba.confиpg_ident.confправить не нужно. - У каждой базы снято право подключения для всех (
REVOKE CONNECT … FROM PUBLIC): войти может только владелец. vx_dev вveilix_prodне попадёт. - Роль владеет своей базой: Payload нужны права на изменение схемы (push в dev, миграции в prod).
- Строка подключения:
postgresql://vx_dev@/veilix_dev?host=/var/run/postgresql(для prod —vx_prod@/veilix_prod).
6. Почта (Postfix)
smtp_bind_address = 169.58.76.183,myhostname = fr-ub2gs3.veilix.cc: письма уходят с IP, у которого обратная запись совпадает с прямой.- OpenDKIM: ключи для veilix.app и veilixvpn.com (селектор, напр.
mail). - DNS для каждого из двух доменов:
a. SPF:
v=spf1 ip4:169.58.76.183 include:<почтовый хостинг> -all. Хостинг нужен, потому что ответы поддержки уходят через него (пункт 5); плюс SMTP-провайдер, если используем; b. DKIM: TXTmail._domainkey.<домен>с открытым ключом; c. DMARC:_dmarc.<домен>— сначалаv=DMARC1; p=none; rua=mailto:…, после проверки —p=quarantine. - Проверить, что хостер не закрывает исходящий порт 25 и что 169.58.76.183 нет в чёрных списках.
- Почта поддержки (Q-16): ящики
help@veilix.appиhelp@veilixvpn.com— на внешнем почтовом хостинге, MX-записи доменов указывают на него (пользователь, R-18). На этапе 3e Chatwoot забирает письма по IMAP и отвечает через SMTP хостинга. Доменов брендов вmydestinationPostfix нет и быть не должно: тогда письма администраторам наhelp@…уходят на хостинг, а не остаются на этом сервере.
7. Бэкапы
- Prod-база: каждую ночь
pg_dump -Fc veilix_prod, хранить 14 ежедневных и 8 еженедельных, копия на другой сервер (куда — Q-14). Раз в месяц — проверочное восстановление в отдельную базу. shared/media— синхронизация на тот же внешний сервер.- Dev не бэкапим: код — в git, данные dev — тестовые.
8. Задачи для root по этапам
| № | Этап | Задача | Статус на 22.10.2026 |
|---|---|---|---|
| R-00 | 0 | Переезд разработки: перенести /home/vx/veilix_dev в /home/vx_dev/veilix_dev (владелец vx_dev); SSH-ключ vx_dev для VSCode; Claude Code под vx_dev |
сделано |
| R-01 | 0 | Репозиторий в Gitea; SSH-ключ vx_dev с правом push; для vx_prod — ключ только на чтение (deploy key) | vx_dev — сделано: origin — ssh://git@gte.apr.sh:26789/andreypr207/veilix.app.git, ключ ~/.ssh/veilix_gitea_ed25519 добавлен в Gitea как deploy key с правом записи, main отправлен. Ключ vx_prod — на этапе 1h |
| R-02 | 1a | PostgreSQL: роли vx_dev, vx_prod, umami и их базы (раздел 5) |
сделано и проверено: vx_dev входит в veilix_dev, в veilix_prod — отказ |
| R-03 | 1a | pnpm: corepack enable pnpm |
сделано |
| R-04 | 1a | Пользователи vx_dev, vx_prod, umami; loginctl enable-linger для них |
сделано |
| R-05 | 1a | nginx и сертификаты для всех хостов (раздел 4) | сделано: опечатка исправлена, X-Robots-Tag на всех dev-хостах |
| R-06 | 1a | MaxMind: geoipupdate (ключ в /etc/GeoIP.conf, база в /var/lib/GeoIP, таймер geoipupdate.timer); отключить старый модуль GeoIP v1; блок geoip2 (раздел 4, пункт 4) |
сделано |
| R-07 | 3c | Postfix, OpenDKIM, DNS-записи SPF, DKIM, DMARC — или данные SMTP-провайдера | |
| R-08 | 3h | PostgreSQL для prod — если не сделано вместе с R-02 | сделано в R-02 |
| R-09 | 3h | nginx и сертификаты для prod-хостов | сделано вместе с R-05 |
| R-10 | 3f | Umami: nginx и сертификат для umi.veilix.cc (DNS уже есть; база — в R-02) |
|
| R-11 | 3h | Бэкапы prod-базы и media на внешний сервер (Q-14) | |
| R-12 | 3d, 3e | VPS с Chatwoot и Twenty, ключи API; 2 бота поддержки в BotFather | |
| R-13 | 2a | Боты в BotFather: 2 основных и тестовые; домен для Telegram Login; адреса MiniApp | |
| R-14 | 3b, 4b | Аккаунты платёжных систем (сначала тестовые), адреса вебхуков | |
| R-15 | 3h | По желанию (Q-18): sudo-правило, разрешающее vx_dev запускать от имени vx_prod только команду выкладки | |
| R-16 | 3h | По желанию: правило nftables — к 127.0.0.1:3000 подключаются только www-data (nginx) и vx_prod (10-security.md, раздел 7) |
|
| R-17 | 1a | nginx dev: отдельный location /_next/hmr с proxy_read_timeout 1h во всех трёх server-блоках dev на 443: dev.plc.veilix.cc, сайты и кабинеты, dev.tg.*. В Next 16.4 WebSocket горячей перезагрузки — /_next/hmr, и сервер может молчать дольше 30 секунд, а nginx.conf закрывает соединение после 30 секунд тишины (proxy_read_timeout 30) |
сделано: на всех семи dev-хостах соединение держится 70 секунд без сообщений |
| R-18 | 3c | Почта поддержки (Q-16): ящики help@veilix.app и help@veilixvpn.com на почтовом хостинге, MX-записи доменов; хостинг — в SPF (раздел 6). До этого письма администраторам и заявки видны только в админке и журнале писем |
|
| R-19 | 1b | Библиотеки для headless Chromium — сверка страниц с макетами по скриншотам и Lighthouse: libatk1.0-0t64 libatk-bridge2.0-0t64 libatspi2.0-0t64 libasound2t64 libxcomposite1 libxdamage1 libxfixes3 libxrandr2. Сам браузер (Chrome for Testing) лежит в папке vx_dev, без root |
сделано 22.10.2026: скриншоты снимаются |