UnicoreCMS

Переменные окружения

Что и зачем вписывать в конфигурацию

Все три приложения читают один .env в корне репозитория. Файл ищется вверх по дереву от рабочей директории, так что запускать процессы можно из любой папки внутри проекта.

Большинство переменных подхватываются при перезапуске. Пересобирать фронты нужно только ради GOOGLE_ANALYTICS_ID, YANDEX_METRIKA_ID, COLOR_MODE_PREFERENCE и COLOR_MODE_FALLBACK: они подключают модули на этапе сборки.

Файл важнее окружения

Порты читаются сначала из .env, и только потом из переменных окружения. Так сделано из-за игровых панелей вроде Pterodactyl: они инжектят свой SERVER_PORT под аллокацию, и без этого приоритета бэкенд уезжал бы на чужой порт. Основное имя теперь BACKEND_PORT, старое SERVER_PORT тоже читается.

Обязательное

Без этих четырёх приложение не стартует.

ПеременнаяЧто это
BASEURLПубличный адрес сайта, например https://example.com
API_BASEURLАдрес API, например https://api.example.com
DATABASE_NAMEИмя базы
JWT_KEYСекрет для подписи токенов

ADMIN_BASEURL можно не заполнять — тогда возьмётся BASEURL с портом из ADMIN_PORT. Серверу он нужен, чтобы разрешить админке CORS.

Проект и время

SITENAME=UnicoreCMS
TIMEZONE=UTC
CLIENT_PORT=3000
ADMIN_PORT=4000
BACKEND_PORT=5000

Временем в проекте управляет одна ручка TIMEZONE. В этой зоне время пишется в базу и показывается на сайте. Берите UTC: он не зависит от переводов часов и не поедет при переносе сервера в другую страну.

База данных

DATABASE_TYPE=mysql
DATABASE_HOST=127.0.0.1
DATABASE_PORT=3306
DATABASE_USER=unicore
DATABASE_PASSWORD=...
DATABASE_NAME=unicore

DATABASE_TYPE понимает mysql, mariadb и postgres.

Секреты

JWT_KEY=...
ENCRYPTION_KEY=
ENCRYPTION_KEY_PREVIOUS=

JWT_KEY подписывает токены доступа. ENCRYPTION_KEY шифрует данные в базе: хеши паролей, пароли RCON, секреты 2FA. Держите их разными, чтобы утечка одного не роняла второе. Если ENCRYPTION_KEY пустой, берётся JWT_KEY.

Оба генерируются одинаково:

openssl rand -hex 32

Потеря ENCRYPTION_KEY необратима

Без ключа никто не сможет войти, а пароли RCON и секреты 2FA не расшифруются. Положите его в бэкап отдельно от базы, иначе бэкап бесполезен.

Смена ключа шифрования

Старый ключ переезжает в ENCRYPTION_KEY_PREVIOUS, новый вписываете в ENCRYPTION_KEY. Дальше одна команда:

pnpm --filter unicore-server exec node dist/cli/main.js crypto-rewrap

Она перешифрует пароли RCON и секреты 2FA. Пароли пользователей перешифруются сами при следующем успешном входе. Когда все зашли, ENCRYPTION_KEY_PREVIOUS можно чистить.

Пароли

PASSWORD_ALGORITHM=argon2id
PASSWORD_ARGON2_MEMORY=65536
PASSWORD_ARGON2_TIME=3
PASSWORD_ARGON2_PARALLELISM=4
PASSWORD_BCRYPT_COST=12

По умолчанию argon2id. Старые bcrypt-хеши читаются в любом случае и молча переезжают на текущий алгоритм при следующем входе, так что миграцию запускать не нужно.

Токены и прокси

JWT_EXPIRES=15m
JWT_REFRESH_EXPIRES=7d
TRUST_PROXY=
CORS_ORIGINS=

Чаще всего странные баги на продакшене устраивает TRUST_PROXY. Если сайт стоит за nginx и переменная пустая, сервер у всех клиентов видит IP прокси. Сразу ломаются троттлинг, антифлуд на сбросе пароля, IP-фильтр API-ключей и проверка вебхуков платёжек.

СхемаЗначение
nginx на том же хостеloopback
Один прокси перед приложением1
docker-compose с профилем nginx1
Приложение смотрит в интернет напрямуюоставить пустым

Пустое значение при живом прокси открывает ещё и дыру: клиент сможет подделать свой IP заголовком X-Forwarded-For.

В CORS_ORIGINS источники перечисляются через запятую. Пустое значение означает BASEURL плюс ADMIN_BASEURL, для большинства проектов этого достаточно.

Почта

MAIL_FROM=no-reply@example.com
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_SECURE=false

Вместо хоста и порта можно указать SMTP_SERVICE, то есть имя провайдера из списка nodemailer (gmail, yandex, mail.ru и другие). Остальное подставится само.

Без рабочего SMTP не уйдут письма активации и сброса пароля. Если активация почты вам не нужна, отключите её в настройках сайта — иначе новые игроки останутся с неактивированными аккаунтами.

Прочее

RECAPTCHA_PUBLIC=
RECAPTCHA_SECRET=
COLOR_MODE_PREFERENCE=light
COLOR_MODE_FALLBACK=light
REAL_DECIMALS=2
VIRTUAL_DECIMALS=2
INGAME_DECIMALS=2

Используется reCAPTCHA третьей версии, пустые ключи просто выключают проверку. В *_DECIMALS задаётся число знаков после запятой для реальной, виртуальной и внутриигровой валюты.

Интеграции

Ключи платёжек, мониторингов и соцсетей описаны там, где о них речь:

Каждая интеграция включается своим *_ENABLED=1. Если включить интеграцию и не заполнить её ключи, сервер откажется стартовать и напишет, чего именно не хватает. Это лучше, чем молча не работающая оплата.

Содержание