Environment Variables
Полный справочник всех переменных окружения для каждого сервиса.
1. Backend
Самый большой набор переменных. Задаются в Dokploy → Backend Service → Environment.
- Core
- Database
- Redis
- Telegram
| Variable | Required | Default | Описание |
|---|---|---|---|
NODE_ENV | Yes | — | production, staging, development |
PORT | Yes | 4000 | Порт, на котором слушает сервер. Задавай 4000 |
HOST | No | 0.0.0.0 | На каком интерфейсе слушать. 0.0.0.0 = все (нужно в Docker) |
LOG_LEVEL | No | info | Уровень логов: error, warn, info, debug |
LOG_PRETTY | No | false | Pretty-print логов (только для dev) |
UPLOAD_DIR | Yes (prod) | — | Путь для загрузки файлов (статика). Проверяется env-validator при запуске |
MAINTENANCE_BYPASS_TELEGRAM_IDS | No | — | Telegram ID пользователей, которые могут обходить режим maintenance (через запятую) |
| Variable | Required | Default | Описание |
|---|---|---|---|
DB_ENV | Yes | dev | Выбор БД: dev, staging, prod |
DATABASE_URL_DEV | Conditional | — | PostgreSQL URL для dev |
DATABASE_URL_STAGING | Conditional | — | PostgreSQL URL для staging |
DATABASE_URL_PROD | Conditional | — | PostgreSQL URL для prod |
DATABASE_URL | No | — | Fallback (если env-specific не найден) |
Способ 1 — через DB_ENV (рекомендуется для multi-env):
DB_ENV=prod → код ищет DATABASE_URL_PROD. Если не найден → fallback на DATABASE_URL.
Способ 2 — напрямую DATABASE_URL (проще для single-env):
Не задаёшь DB_ENV → код использует DATABASE_URL напрямую. Подходит если одно окружение на сервер.
Логика: database.config.ts → сначала ищет env-specific URL (DATABASE_URL_{DB_ENV}), потом fallback на DATABASE_URL.
| Variable | Required | Default | Описание |
|---|---|---|---|
REDIS_URL | No | redis://localhost:6379 | Redis URL. Пароль передаётся прямо в URL: redis://:PASSWORD@host:6379 |
Пароль зависит от настройки Redis-сервиса в Dokploy. Если при создании Redis в Dokploy ты не задавал пароль — используй URL без него: redis://hostname:6379. Если задавал — передавай в URL: redis://:PASSWORD@hostname:6379.
Hostname контейнера Redis в Dokploy — не redis, а сгенерированное имя (например, goloot-redis-ix89rh). Узнать его: Dokploy UI → Redis Service → General → Container Name. Используй это имя в REDIS_URL.
| Variable | Required | Default | Описание |
|---|---|---|---|
TELEGRAM_BOT_TOKEN | Yes | — | Токен бота от @BotFather |
TELEGRAM_BOT_USERNAME | Yes | — | Username бота (без @) |
TELEGRAM_APP_NAME | Yes | — | Имя Mini App в Telegram |
TELEGRAM_MINI_APP_URL | Yes | — | Deep link на Mini App (https://t.me/botName/appName) |
TELEGRAM_WEBHOOK_URL | Yes | — | URL для webhook-ов от Telegram |
TELEGRAM_WEBHOOK_SECRET | No | — | Secret token для верификации webhook-запросов (мин. 32 символа) |
TELEGRAM_CHANNEL_ID | No | — | ID канала для уведомлений |
TELEGRAM_CHANNEL_USERNAME | No | — | Username канала (используется и backend, и frontend) |
TELEGRAM_DISCUSSION_GROUP_ID | No | — | ID группы обсуждений |
TELEGRAM_GROUP_ID | No | — | ID основной группы |
TELEGRAM_ADMIN_IDS | No | — | Whitelist Telegram user ID (через запятую) для admin-кнопок в группе |
TELEGRAM_TOPIC_BAN_APPEAL | No | — | Апелляции забаненных пользователей (кнопка «Открыть апелляцию» → админка) |
TELEGRAM_TOPIC_PROBLEM | No | — | Жалобы от пользователей + проблемы с выводом скинов |
TELEGRAM_TOPIC_SUGGESTION | No | — | Предложения от пользователей через форму обратной связи |
TELEGRAM_TOPIC_VERIFICATION | No | — | Заявки на верификацию Steam (Trade URL для проверки) |
TELEGRAM_TOPIC_SEASONS | No | — | Всё про сезоны: старт, конец, countdown, валидация, напоминание о наградах |
TELEGRAM_TOPIC_RAFFLES | No | — | Розыгрыши: пул призов пуст, новый розыгрыш не создан |
TELEGRAM_TOPIC_BUDGET | No | — | Экономика: обновление Luck Pool, смена бюджетного периода |
TELEGRAM_TOPIC_SECURITY | No | — | Безопасность: бюджет исчерпан, подозрительная крафт-активность (фрод) |
TELEGRAM_TOPIC_TRADES | No | — | Уведомления о трейдах Steam (отправка/получение скинов) |
TELEGRAM_TOPIC_REPLIES | No | — | Ответы админа на тикеты пользователей |
TELEGRAM_QUIZ_TTL_SECONDS | No | 86400 | TTL публикаций квизов в Telegram канале (сек). По умолчанию 24 часа |
Правильный URL: https://api.goloot.online/api/telegram/webhook — консистентно с остальными API routes.
Если задан — Telegram присылает его в заголовке X-Telegram-Bot-Api-Secret-Token, backend проверяет при каждом webhook-запросе. Без него webhook принимает запросы от кого угодно.
TELEGRAM_TOPIC_* роутят уведомления в топики (треды) Telegram-группы. Если ID не задан — уведомление уходит в общий чат.
Как получить ID топика: открой группу с включёнными Topics → правый клик на нужный топик → Copy Link → в URL будет ?topic=123 — число 123 и есть ID.
- JWT & Auth
- Steam
- URLs
- Monitoring
- Quiz Generation
- Economy
| Variable | Required | Default | Описание |
|---|---|---|---|
JWT_SECRET | Yes | — | Секрет для подписи JWT (мин. 32 символа). Генерация: openssl rand -base64 48 |
JWT_EXPIRES_IN | Yes | 7d | Время жизни токена |
ADMIN_USERNAME | No | — | Логин админ-панели |
ADMIN_PASSWORD_HASH | No | — | Bcrypt-хэш пароля админ-панели (cost 12). См. генерацию ниже |
ENABLE_2FA | No | false | Включить двухфакторную аутентификацию для админ-панели |
ADMIN_2FA_SECRET | Conditional | — | TOTP-секрет для 2FA. Обязателен если ENABLE_2FA=true |
DOCS_OWNER_TTL_MINUTES | No | 240 | TTL сессии доступа к документации для владельца (мин.) |
DOCS_ADMIN_TTL_MINUTES | No | 240 | TTL сессии доступа к документации для админа (мин.) |
Пароль хэшируется через bcrypt с cost 12. Сгенерировать хэш:
# Через Node.js (bcryptjs уже в зависимостях проекта)
node -e "const b=require('bcryptjs');b.hash('YOUR_PASSWORD',12).then(h=>console.log(h))"
Полученный хэш (начинается с $2a$12$...) — это значение ADMIN_PASSWORD_HASH.
ENABLE_2FA в backend и VITE_ENABLE_2FA в Admin Panel должны совпадать. Если backend = false, а admin = true — админка покажет поле ввода 2FA-кода, но backend его проигнорирует.
| Variable | Required | Default | Описание |
|---|---|---|---|
STEAM_API_KEY | No | — | Steam API ключ |
STEAM_ENABLED | No | true | Включить Steam-бота |
STEAM_USERNAME | Conditional | — | Логин Steam-аккаунта |
STEAM_PASSWORD | Conditional | — | Пароль Steam-аккаунта |
STEAM_SHARED_SECRET | Conditional | — | Shared Secret для 2FA |
STEAM_IDENTITY_SECRET | Conditional | — | Identity Secret для подтверждений |
STEAM_ADMIN_IDS | No | — | Steam ID администраторов (через запятую). Используется для привилегированных операций в Steam-боте |
В NODE_ENV=production Steam-бот обязателен по умолчанию. Если не нужен — задай STEAM_ENABLED=false.
| Variable | Required | Default | Описание |
|---|---|---|---|
STATIC_URL | Yes | — | URL сервера статики |
WEB_APP_URL | Yes | — | URL фронтенда |
ADMIN_URL | No | — | URL админ-панели |
REDIRECT_START_URL | Yes | — | URL redirect-сервиса (referral/UTM ссылки) |
REDIRECT_PUSH_URL | Yes | — | URL redirect-сервиса (push tracking) |
BROWSER_URL | No | — | Публичный URL для браузера |
| Variable | Required | Default | Описание |
|---|---|---|---|
OTEL_SERVICE_NAME | No | goloot-backend | Имя сервиса в трейсах |
OTEL_EXPORTER_OTLP_ENDPOINT | No | — | Endpoint для OpenTelemetry |
ENABLE_SWAGGER | No | true | Включить Swagger UI |
SWAGGER_API_KEY | No | — | API-ключ для Swagger |
| Variable | Required | Default | Описание |
|---|---|---|---|
QUIZ_SQLITE_PATH | No | {cwd}/data/rust_data.db | Путь к SQLite базе с данными Rust предметов |
SQLite файл (~29 MB) хранится на хосте в /var/data/goloot/rust_data.db и монтируется в контейнер через bind mount. Без него генерация квизов не работает.
| Variable | Required | Default | Описание |
|---|---|---|---|
REFERRAL_BONUS_XP | No | 100 | XP-бонус за реферала |
REFERRAL_BONUS_SCRAP_REFERRED | No | 500 | Scrap-бонус приглашённому пользователю |
REFERRAL_PASSIVE_INCOME_PERCENT | No | 10 | Процент пассивного дохода от рефералов |
UTM_BONUS_SCRAP | No | 200 | Scrap-бонус за переход по UTM-ссылке |
Каждая имеет дефолтное значение в коде (referrals/config.ts, utm/utm-reward.service.ts). Задавай в env только если хочешь переопределить.
Пример .env для Production
Полный пример .env для Backend (production)
# === Core ===
NODE_ENV=production
PORT=4000
HOST=0.0.0.0
LOG_LEVEL=info
UPLOAD_DIR=/var/data/goloot/uploads
MAINTENANCE_BYPASS_TELEGRAM_IDS=123456789,987654321 # Bypass maintenance mode
# === Database ===
# Способ 1: через DB_ENV
DB_ENV=prod
DATABASE_URL_PROD=postgresql://goloot:STRONG_PASSWORD@goloot-postgresql-XXXXX:5432/goloot
# Способ 2: напрямую (если одно окружение на сервер)
# DATABASE_URL=postgresql://goloot:STRONG_PASSWORD@goloot-postgresql-XXXXX:5432/goloot
# === Redis ===
# Hostname — Container Name из Dokploy UI (НЕ просто "redis")
REDIS_URL=redis://:REDIS_PASSWORD@goloot-redis-XXXXX:6379
# === JWT & Auth ===
JWT_SECRET=СГЕНЕРИРУЙ_ЧЕРЕЗ_openssl_rand_base64_48
JWT_EXPIRES_IN=7d
ADMIN_USERNAME=admin
ADMIN_PASSWORD_HASH=BCRYPT_HASH
ENABLE_2FA=true
ADMIN_2FA_SECRET=СГЕНЕРИРУЙ_ЧЕРЕЗ_openssl_rand_base64_32
# === Docs Access ===
DOCS_OWNER_TTL_MINUTES=240
DOCS_ADMIN_TTL_MINUTES=240
# === Telegram ===
TELEGRAM_BOT_TOKEN=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
TELEGRAM_BOT_USERNAME=GoLootBot
TELEGRAM_APP_NAME=goloot
TELEGRAM_MINI_APP_URL=https://t.me/GoLootBot/goloot
TELEGRAM_WEBHOOK_URL=https://api.goloot.online/api/telegram/webhook
TELEGRAM_WEBHOOK_SECRET=СГЕНЕРИРУЙ_ЧЕРЕЗ_openssl_rand_hex_32
TELEGRAM_CHANNEL_ID=-1001234567890
TELEGRAM_CHANNEL_USERNAME=goloot_channel
TELEGRAM_DISCUSSION_GROUP_ID=-1001234567890
TELEGRAM_GROUP_ID=-1001234567890
TELEGRAM_ADMIN_IDS=123456789,987654321
# === Telegram Topics (опционально) ===
# ID топиков (тредов) в Telegram-группе. Каждый — реальное число из URL топика.
# Как узнать: группа → правый клик на топик → Copy Link → ?topic=ЧИСЛО
TELEGRAM_TOPIC_BAN_APPEAL=123 # Апелляции забаненных
TELEGRAM_TOPIC_PROBLEM=456 # Жалобы и проблемы с выводом
TELEGRAM_TOPIC_SUGGESTION=789 # Предложения пользователей
TELEGRAM_TOPIC_VERIFICATION=101 # Заявки на верификацию Steam
TELEGRAM_TOPIC_SEASONS=102 # Сезоны (старт, конец, валидация)
TELEGRAM_TOPIC_RAFFLES=103 # Розыгрыши (пул призов пуст)
TELEGRAM_TOPIC_BUDGET=104 # Экономика (Luck Pool, смена периода)
TELEGRAM_TOPIC_SECURITY=105 # Безопасность (фрод, бюджет исчерпан)
TELEGRAM_TOPIC_TRADES=107 # Трейды Steam (отправка/получение скинов)
TELEGRAM_TOPIC_REPLIES=106 # Ответы админа на тикеты
TELEGRAM_QUIZ_TTL_SECONDS=86400 # TTL публикаций квизов (24 часа)
# === Steam ===
STEAM_ENABLED=true
STEAM_API_KEY=your-steam-api-key
STEAM_USERNAME=your-steam-username
STEAM_PASSWORD=your-steam-password
STEAM_SHARED_SECRET=your-shared-secret
STEAM_IDENTITY_SECRET=your-identity-secret
STEAM_ADMIN_IDS=76561198000000001,76561198000000002 # Steam ID админов
# === URLs ===
STATIC_URL=https://static.goloot.online
WEB_APP_URL=https://goloot.online
ADMIN_URL=https://admin.goloot.online
REDIRECT_START_URL=https://start.goloot.online
REDIRECT_PUSH_URL=https://r.goloot.online
# === Quiz Generation ===
QUIZ_SQLITE_PATH=/var/data/goloot/rust_data.db
# === Monitoring ===
OTEL_SERVICE_NAME=goloot-backend
OTEL_EXPORTER_OTLP_ENDPOINT=http://tempo:4318
ENABLE_SWAGGER=true
SWAGGER_API_KEY=your-swagger-api-key
# === Economy (опционально — есть дефолты в коде) ===
REFERRAL_BONUS_XP=100
REFERRAL_BONUS_SCRAP_REFERRED=500
REFERRAL_PASSIVE_INCOME_PERCENT=10
UTM_BONUS_SCRAP=200
2. Frontend
Frontend использует build-time переменные с префиксом VITE_.
В Dokploy задавай эти переменные как Build-time Variables (Build Args), а не как Environment Variables. Vite вшивает их в статику при сборке.
| Variable | Required | Default | Описание |
|---|---|---|---|
VITE_API_URL | No | http://localhost:4000 | Backend API URL |
VITE_STATIC_URL | No | https://static.goloot.online | URL сервера статики (для картинок предметов, кейсов, аватаров) |
VITE_TELEGRAM_BOT_USERNAME | No | — | Username бота |
VITE_TELEGRAM_CHANNEL_USERNAME | No | — | Username канала |
VITE_REDIRECT_START_URL | No | — | URL redirect-сервиса (referral/UTM) |
VITE_SEQUENTIAL_API_TIMEOUT | No | 5000 | Таймаут API (мс) |
VITE_SEQUENTIAL_TOTAL_TIMEOUT | No | 15000 | Общий таймаут (мс) |
VITE_AD_FETCH_TIMEOUT | No | 3000 | Таймаут рекламы (мс) |
VITE_FAVORITES_CACHE_TTL | No | — | TTL кэша избранного |
VITE_BANNER_HIDE_DURATION | No | — | Скрытие баннера (мс) |
3. Admin Panel
Тоже build-time переменные с VITE_:
| Variable | Required | Default | Описание |
|---|---|---|---|
VITE_API_URL | No | http://localhost:4000 | Backend API URL |
VITE_STATIC_URL | No | — | URL статики |
VITE_REDIRECT_START_URL | No | — | URL redirect-сервиса (referral/UTM) |
VITE_REDIRECT_PUSH_URL | No | — | URL redirect-сервиса (push tracking) |
VITE_ENABLE_2FA | No | — | Включить 2FA |
VITE_GRAFANA_URL | No | — | URL Grafana |
4. Redirect Service
Все переменные обязательны — сервис упадёт при отсутствии:
| Variable | Required | Default | Описание |
|---|---|---|---|
NODE_ENV | Yes | — | Окружение |
PORT | Yes | — | Порт (3001) |
HOST | Yes | — | Хост (0.0.0.0) |
LOG_LEVEL | Yes | — | Уровень логов |
DATABASE_URL | Yes | — | PostgreSQL URL |
STATIC_URL | Yes | — | URL статики |
START_URL | Yes | — | URL фронтенда (куда редиректить пользователя) |
TELEGRAM_BOT_USERNAME | Yes | — | Username бота |
TELEGRAM_APP_NAME | Yes | — | Имя приложения |
5. Monitoring Stack
Переменные задаются в Dokploy → monitoring compose → Environment:
| Variable | Service | Default | Описание |
|---|---|---|---|
GRAFANA_ADMIN_USER | Grafana | admin | Логин Grafana |
GRAFANA_ADMIN_PASSWORD | Grafana | admin | Пароль Grafana |
Grafana Service Account Token
Для API-доступа к Grafana (автоматизация, AI-диагностика) используется Service Account Token вместо логина/пароля:
| Параметр | Значение |
|---|---|
| Создание | Grafana UI → Administration → Service Accounts |
| Роль | Viewer (read-only) |
| Формат токена | glsa_xxxxxxxxxxxx |
| Хранение | Вне git: ~/.claude/projects/.../grafana-token или локальный .env |
| Использование | Authorization: Bearer glsa_xxx header |
GRAFANA_ADMIN_PASSWORD — пароль для входа в UI. Service Account Token — для программного API-доступа. Это разные механизмы аутентификации.
Подробнее: Monitoring Setup → Grafana API
6. GitHub Actions Secrets
Для CI/CD пайплайна нужны секреты в GitHub:
| Secret | Описание |
|---|---|
SWAGGER_API_KEY | Ключ для получения OpenAPI spec |
DOKPLOY_DOCS_WEBHOOK | Webhook URL для деплоя документации |
Подробнее: CI/CD Setup
7. Генерация секретов
# JWT Secret (64 символа, base64 допустим — используется только в коде)
openssl rand -base64 48
# Пароль для PostgreSQL (hex — без спецсимволов, безопасен в connection string)
openssl rand -hex 24
# Пароль для Redis (hex — без спецсимволов, безопасен в connection string)
openssl rand -hex 24
# Swagger API Key
openssl rand -hex 32
# ADMIN_2FA_SECRET (TOTP-секрет для 2FA админ-панели, base64)
openssl rand -base64 32
# TELEGRAM_WEBHOOK_SECRET (hex, мин. 32 символа)
openssl rand -hex 32
# ADMIN_PASSWORD_HASH (bcrypt, cost 12)
node -e "const b=require('bcryptjs');b.hash('YOUR_PASSWORD',12).then(h=>console.log(h))"
openssl rand -base64 генерирует символы /, +, = — они ломают PostgreSQL connection string и могут вызвать проблемы в shell. openssl rand -hex выдаёт только 0-9, a-f — безопасно везде.
Related
- Services Deployment — где задавать переменные
- Database Setup — connection strings
- Monitoring Setup — Grafana credentials