- Q-02: цены mass в USD $6.99 и $69.90, пресеты пополнения в RUB и USD. - D-025: реферальный бонус — 30 дней к ключу обоим вместо денег; продления без оплаты (key-extensions); крайние случаи — Q-19. - Q-08, Q-09: help@veilix.app и help@veilixvpn.com, часы по Москве. - Q-16: ящики на почтовом хостинге (R-18), на этапе 2 — Chatwoot по IMAP. - R-01 сделано; R-17: путь HMR в Next 16.4 — /_next/hmr. 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.* (этап 3) разрешить показ во фрейме 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). На этапе 2 Chatwoot забирает письма по IMAP и отвечает через SMTP хостинга. Доменов брендов вmydestinationPostfix нет и быть не должно: тогда письма администраторам наhelp@…уходят на хостинг, а не остаются на этом сервере.
7. Бэкапы
- Prod-база: каждую ночь
pg_dump -Fc veilix_prod, хранить 14 ежедневных и 8 еженедельных, копия на другой сервер (куда — Q-14). Раз в месяц — проверочное восстановление в отдельную базу. shared/media— синхронизация на тот же внешний сервер.- Dev не бэкапим: код — в git, данные dev — тестовые.
8. Задачи для root по этапам
| № | Этап | Задача | Статус на 21.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 | 1c | Postfix, OpenDKIM, DNS-записи SPF, DKIM, DMARC — или данные SMTP-провайдера | |
| R-08 | 1h | PostgreSQL для prod — если не сделано вместе с R-02 | сделано в R-02 |
| R-09 | 1h | nginx и сертификаты для prod-хостов | сделано вместе с R-05 |
| R-10 | 1h | Umami: nginx и сертификат для umi.veilix.cc (DNS уже есть; база — в R-02) |
|
| R-11 | 1h | Бэкапы prod-базы и media на внешний сервер (Q-14) | |
| R-12 | 2 | VPS с Chatwoot и Twenty, ключи API; 2 бота поддержки в BotFather | |
| R-13 | 3 | Боты в BotFather: 2 основных и тестовые; домен для Telegram Login; адреса MiniApp | |
| R-14 | 4 | Аккаунты платёжных систем (сначала тестовые), адреса вебхуков | |
| R-15 | 1h | По желанию (Q-18): sudo-правило, разрешающее vx_dev запускать от имени vx_prod только команду выкладки | |
| R-16 | 1h | По желанию: правило 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) |
в работе: сначала в задаче был старый путь /_next/webpack-hmr. Блоки с ним в dev.plc и dev.tg.* не срабатывают — их переименовать; в блоке сайтов и кабинетов блока нет |
| R-18 | 1h | Почта поддержки (Q-16): ящики help@veilix.app и help@veilixvpn.com на почтовом хостинге, MX-записи доменов; хостинг — в SPF (раздел 6). До этого письма администраторам и заявки видны только в админке и журнале писем |