# ═══════════════════════════════════════════════════════════════════════════ # Forbidden Stars — единый .env (dev / prod) # Скопируйте в .env, заполните секреты. Реальный .env в git НЕ идёт. # Окружение — строкой APP_ENV (ниже); публикация локалки наружу — LOCAL_PUBLIC. # ═══════════════════════════════════════════════════════════════════════════ # ─── ГЛАВНЫЙ ПЕРЕКЛЮЧАТЕЛЬ ──────────────────────────────────────────────────── # Этот параметр читает ЛАУНЧЕР (run.ps1 / run.sh) и решает, что запускать: # development — нативно: uvicorn --reload + vite, БД в ./data/dev/, вход TG+ник # production — НЕ запускается лаунчером; деплой на Pi отдельно (docker compose up -d). # Прод-контейнер ИГНОРИРУЕТ это значение и всегда production. APP_ENV=development # ─── ПУБЛИКАЦИЯ ЧЕРЕЗ ДОМЕН (VPS-туннель) ───────────────────────────────────── # LOCAL_PUBLIC — только для DEV на твоём ПК: local = приложение лишь на localhost; # vps = лаунчер (run.ps1) дополнительно поднимает SSH-туннель → дев на forbidden-stars.ru. # Тогда любому посетителю домена открыты dev-инструменты: вход по нику без пароля, # список/создание игроков, жёсткое удаление аккаунтов, Swagger. Дефолтные SECRET_KEY # и ADMIN_PASSWORD при vps не дают стартовать — задайте свои (#69). # PROD выставляет себя сам через туннель-КОНТЕЙНЕР (docker-compose*.yml) — ему # LOCAL_PUBLIC не нужен, но VPS_TUNNEL_HOST/USER ниже он тоже читает. LOCAL_PUBLIC=local # Параметры VPS: их читают и dev-туннель (run.ps1), и туннель-контейнер прода. # Ключ туннеля — в deploy/tunnel/id_tunnel (в git не идёт); pubkey → authorized_keys у tunnel@VPS. VPS_TUNNEL_HOST=186.246.51.17 VPS_TUNNEL_USER=tunnel # VPS_TUNNEL_PORT обычно НЕ задают — каждый контур берёт свой слот по умолчанию: # dev (run.ps1) → 9001, прод-контейнер → 9000. # Раскомментируй и переопредели, только если нужен нестандартный слот. #VPS_TUNNEL_PORT=9001 # Приватный ключ туннеля в base64 — чтобы на Pi хватило только docker-compose.yml + .env # (без файла deploy/tunnel/id_tunnel). Нужен ТОЛЬКО для прод-контейнера на Pi; временный прод # на ПК берёт ключ из файла. Сгенерируй ключ на ПК и закодируй БЕЗ переносов строк: # Git Bash / Linux: base64 -w0 deploy/tunnel/id_tunnel # PowerShell: [Convert]::ToBase64String([IO.File]::ReadAllBytes((Resolve-Path "deploy/tunnel/id_tunnel"))) # Pubkey (deploy/tunnel/id_tunnel.pub) добавь в authorized_keys у tunnel@VPS. TUNNEL_KEY_B64= # ─── АДМИНИСТРАТОР (вход по логину/паролю, отдельно от Telegram) ────────────── ADMIN_USERNAME=admin ADMIN_PASSWORD=change-me-admin-password ADMIN_NICKNAME=Администратор ADMIN_BOOTSTRAP_ENABLED=true # ─── АУТЕНТИФИКАЦИЯ ИГРОКОВ ─────────────────────────────────────────────────── # Методы входа задаёт APP_ENV: dev → Telegram + stub (вход по нику), prod → только # Telegram. Для Telegram нужны токен и юзернейм бота (@BotFather). /setdomain у # BotFather укажи на ОБА домена, где открывается виджет: forbiddenstars.ru (prod) # и forbidden-stars.ru (dev). TELEGRAM_BOT_TOKEN= TELEGRAM_BOT_USERNAME= # Внешний адрес (зарезервировано): prod https://forbiddenstars.ru; dev https://forbidden-stars.ru. PUBLIC_BASE_URL= # ─── БЕЗОПАСНОСТЬ / СЕССИИ ──────────────────────────────────────────────────── # Сгенерировать: python -c "import secrets;print(secrets.token_urlsafe(48))" # ВАЖНО: в секретах НЕ используйте символ '$' — docker compose трактует его как # подстановку переменной (token_urlsafe даёт только [A-Za-z0-9_-], это безопасно). # У dev и prod ключи должны быть РАЗНЫМИ: иначе токен, подписанный на dev, примет прод. SECRET_KEY=change-me-dev-secret-not-for-production JWT_ALGORITHM=HS256 JWT_USER_TTL_MINUTES=10080 JWT_ADMIN_TTL_MINUTES=480 # COOKIE_SECURE задаётся АВТОМАТИЧЕСКИ по окружению (HTTPS-домен ⇒ Secure-cookie): # dev+localhost → false; dev через VPS, prod → true. Вручную задавать НЕ нужно. COOKIE_DOMAIN= # ─── БАЗА ДАННЫХ (структура общая, файлы РАЗНЫЕ; выбор по APP_ENV) ──────────── # dev → DEV_DATABASE_URL (файл в ./data/dev/); prod → PROD_DATABASE_URL # (том /data контейнера, см. docker-compose*.yml). DEV_DATABASE_URL=sqlite:///./data/dev/forbidden_stars.db PROD_DATABASE_URL=sqlite:////data/forbidden_stars.db # Каталог загрузок (фото партий), раздельно для dev и prod. DEV_UPLOAD_DIR=./data/dev/uploads PROD_UPLOAD_DIR=/data/uploads # Каталог определений титулов (файлы: meta.json, condition.py, icon.*), раздельно. DEV_ACHIEVEMENTS_DIR=./data/dev/achievements PROD_ACHIEVEMENTS_DIR=/data/achievements # ─── ОБРАЗЫ ПРОДА (реестр для docker compose pull на Pi) ────────────────────── # Образы собираются под arm64 на ПК (scripts/build-push.sh) и пушатся в Gitea-реестр, # а Pi их тянет (docker compose pull). Owner в пути — строчными. Тег можно версионировать. # Перед пушем/пуллом: docker login gitea.arseniev.info IMAGE_REGISTRY=gitea.arseniev.info/notbigghost IMAGE_TAG=latest # ─── РЕСУРСЫ ПРОД-КОНТЕЙНЕРА (docker-compose.yml) ───────────────────────────── # Лимиты под Raspberry Pi. Не заданы → дефолты compose (512m / 1.5 CPU). # Подними, если у Pi больше RAM/ядер. Лимит памяти работает, только если на Pi включён # memory cgroup (cgroup_enable=memory в cmdline.txt) — см. deploy/pi/README.md, раздел 1. #APP_MEM_LIMIT=512m #APP_CPUS=1.5 # ─── БЭКАПЫ (контейнер backup: restic; подробно — deploy/backup/README.md) ──── # Снимки БД + uploads + achievements по расписанию: локально на Pi (том backup-data) и — # если задан BACKUP_VPS_HOST — на VPS по SFTP. Шифрование, дедупликация, сжатие — restic. # # Пароль шифрования репозиториев. ПОТЕРЯЕТЕ ПАРОЛЬ — НИ ОДИН БЭКАП НЕ ПРОЧИТАТЬ. # Сохраните его в менеджер паролей. Пусто = бэкапы отключены. Без символа '$'. # Сгенерировать: python -c "import secrets;print(secrets.token_urlsafe(32))" BACKUP_PASSWORD= # Когда делать бэкап и проверку данных (cron: минута час день месяц день_недели; TZ ниже). BACKUP_SCHEDULE="0 4 * * *" BACKUP_VERIFY_SCHEDULE="30 5 * * 0" BACKUP_TZ=Europe/Moscow # Сколько хранить: последний снимок каждого дня / недели / месяца. # Именованные снимки (fs-backup run --tag …) и страховочные pre-restore не удаляются. BACKUP_KEEP_DAILY=14 BACKUP_KEEP_WEEKLY=8 BACKUP_KEEP_MONTHLY=12 # Сжатие restic: auto (быстрее) | max (плотнее) | off. BACKUP_COMPRESSION=max # Контейнер помечается unhealthy, если последний успешный бэкап старше стольких часов. BACKUP_MAX_AGE_HOURS=30 # Оффсайт-копия на VPS (SFTP). Пусто = только локальная копия на Pi. BACKUP_VPS_HOST= BACKUP_VPS_USER=fsbackup BACKUP_VPS_PORT=22 BACKUP_VPS_DIR=/srv/fs-backups/restic # Приватный SSH-ключ для VPS в base64 одной строкой (как TUNNEL_KEY_B64). На ПК ключ лежит # в deploy/backup/id_backup (в git НЕ идёт), pubkey — в authorized_keys у fsbackup@VPS. # PowerShell: [Convert]::ToBase64String([IO.File]::ReadAllBytes((Resolve-Path "deploy\backup\id_backup"))) BACKUP_SSH_KEY_B64= # Отчёты о бэкапах в Telegram и команды /backups, /status (deploy/backup/README.md, раздел 10). # id своего чата: напишите боту /start → `docker compose exec backup fs-backup telegram chats`. Несколько — через # запятую. Пусто = отчёты выключены. Токен по умолчанию — TELEGRAM_BOT_TOKEN приложения. BACKUP_TELEGRAM_CHAT_ID= #BACKUP_TELEGRAM_BOT_TOKEN= # Только для ПК (scripts/fs-backup.ps1 / .sh): как зайти на Pi по SSH и где там лежит # docker-compose.yml прода. BACKUP_PI_SSH=pi@192.168.1.10 BACKUP_PI_DIR=~/forbidden-stars # ─── ПРОЧЕЕ ─────────────────────────────────────────────────────────────────── # Часовой пояс приложения (фикс. смещение в часах; МСК = 3) APP_TZ_OFFSET_HOURS=3 # CORS нужен только в dev (фронт и API на разных портах); в prod single-origin CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173 LOG_LEVEL=INFO