Files
chatballs/apps/backend/chatballs_backend/settings_env.py
T
AndreyandClaude Opus 5 a2e6672424 🔥 chore: .env убран отовсюду — установка не читает файл с переменными
Переход на запуск без .env (41a4b0d) не был доведён: в дереве остались файл
`env.example`, чтение instance .env во всём deploy/cli и CI, который этот .env
сам же и создавал из `env.example`. Из-за остатков ломались две вещи.

`chatballs deploy` не работал на установке без .env: _normalize_schema_ownership
брал POSTGRES_USER и POSTGRES_DB из файла и падал с «POSTGRES_USER not set»,
хотя установка исправна. Теперь берёт те же значения по умолчанию, что compose.

`chatballs doctor` выдавал пять ложных ошибок подряд: искал в .env домены,
ACME-почту, POSTGRES_PASSWORD и CHATBALLS_SECRET_KEY. Первое задаёт владелец
в «Настройках», второе генерирует в том с секретами первый старт стека —
снаружи, с хоста, этого не видно, и проверки убраны.

Убрано: env.example (из репозитория, release bundle и README); instance_env_file()
и все его чтения в common/compose/deploy/doctor/status; --env-file instance .env
из вызова compose — остаётся только release.env с digest-пинами образов от CI;
создание .env в gateway:validate. Профиль calls и его адреса читаются из
переменных окружения — оттуда же, откуда их берёт сам compose.

Тесты CLI переведены с фиктивного .env на переменные окружения; три проверки
удалённого поведения doctor убраны. Девять оставшихся проходят вообще без .env
— это и есть проверка, что установка теперь обслуживается. Заодно у
test_custocrm_cli.py выправлены окончания строк: в файле были одиночные CR
внутри кода, отчего diff по нему больше содержательной правки.

Проверено: pytest tests/cli — 9 passed; docker compose config валиден с пустым
каталогом инстанса; bash -n чист по всем скриптам CLI.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-08 17:22:29 +03:00

43 lines
1.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
from pathlib import Path
# Секреты инстанса генерируются при первом старте и лежат файлами в томе
# (deploy/secrets/generate-instance-secrets.sh). В .env их нет — установка не
# требует от человека ни одной переменной.
SECRETS_DIR = Path(os.environ.get("CHATBALLS_SECRETS_DIR", "/run/chatballs/secrets"))
def env_secret(name: str, secret_file: str, default: str = "") -> str:
"""Значение из переменной окружения, иначе из файла секрета, иначе default.
Штатный источник — файл в томе: файла с переменными у продукта нет.
Переменная окружения остаётся выше по приоритету для контуров, которые
подставляют значения средствами оркестратора (облако, CI).
"""
value = os.environ.get(name)
if value:
return value
path_override = os.environ.get(f"{name}_FILE")
path = Path(path_override) if path_override else SECRETS_DIR / secret_file
try:
content = path.read_text(encoding="utf-8").strip()
except OSError:
return default
return content or default
def env_bool(name: str, default: bool = False) -> bool:
value = os.environ.get(name)
if value is None:
return default
return value.lower() in {"1", "true", "yes", "on"}
def env_list(name: str, default: list[str]) -> list[str]:
value = os.environ.get(name)
if value is None:
return default
return [item.strip() for item in value.split(",") if item.strip()]