refactor(deploy): standardize enterprise environment file
This commit is contained in:
@@ -1,107 +0,0 @@
|
|||||||
# #region env.enterprise-clean [C:2] [TYPE Module] [SEMANTICS env,docker,enterprise]
|
|
||||||
# @BRIEF Переменные окружения для docker-compose.enterprise-clean.yml.
|
|
||||||
# Сервисы собираются из исходников или загружаются из pre-built .tar.xz.
|
|
||||||
# PostgreSQL запускается в контейнере (сервис db).
|
|
||||||
# @LAYER Infrastructure
|
|
||||||
# @RELATION DEPENDS_ON -> [docker-compose.enterprise-clean.yml]
|
|
||||||
# #endregion env.enterprise-clean
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# PostgreSQL (контейнер) — настройки встроенной БД
|
|
||||||
# ======================================================================
|
|
||||||
# Для использования внешнего PostgreSQL — переопределите POSTGRES_HOST
|
|
||||||
# и удалите/закомментируйте сервис db в docker-compose.enterprise-clean.yml.
|
|
||||||
POSTGRES_HOST=db
|
|
||||||
POSTGRES_PORT=5432
|
|
||||||
POSTGRES_DB=ss_tools
|
|
||||||
POSTGRES_USER=postgres
|
|
||||||
POSTGRES_PASSWORD=change-me
|
|
||||||
POSTGRES_HOST_PORT=5432
|
|
||||||
|
|
||||||
# Однократный универсальный reset старой Alembic-схемы перед baseline.
|
|
||||||
# Можно оставить true: после применения 0001_baseline последующие старты безопасно пропускают reset.
|
|
||||||
# Непустая БД без таблицы alembic_version никогда не удаляется автоматически.
|
|
||||||
RESET_DATABASE_SCHEMA=true
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# Порты хоста
|
|
||||||
# ======================================================================
|
|
||||||
BACKEND_HOST_PORT=8001
|
|
||||||
FRONTEND_HOST_PORT=8000
|
|
||||||
FRONTEND_SSL_PORT=443
|
|
||||||
AGENT_HOST_PORT=7860
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# Безопасность (ОБЯЗАТЕЛЬНО)
|
|
||||||
# ======================================================================
|
|
||||||
# JWT-ключ подписи токенов — единый для backend и agent.
|
|
||||||
# Сгенерировать: python3 -c "import secrets; print(secrets.token_urlsafe(32))"
|
|
||||||
AUTH_SECRET_KEY=change-me-to-a-random-secret-32-chars-min
|
|
||||||
|
|
||||||
# Fernet-ключ шифрования паролей подключений и API-ключей.
|
|
||||||
# Сгенерировать: python3 -c "import base64,os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())"
|
|
||||||
ENCRYPTION_KEY=change-me-generate-a-fernet-key
|
|
||||||
|
|
||||||
# Сервисный токен для agent→backend вызовов.
|
|
||||||
# Сгенерировать: python3 -c "import secrets; print('svc-' + secrets.token_urlsafe(24))"
|
|
||||||
SERVICE_JWT=replace-with-random-service-secret
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# Сертификаты (корпоративные)
|
|
||||||
# ======================================================================
|
|
||||||
CERTS_PATH=./certs
|
|
||||||
SSL_KEY_PASSPHRASE=
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# LLM / AI провайдеры
|
|
||||||
# ======================================================================
|
|
||||||
OPENAI_API_KEY=
|
|
||||||
ANTHROPIC_API_KEY=
|
|
||||||
# Агент: LLM настройки (если не подтягиваются из FastAPI /api/agent/llm-config)
|
|
||||||
LLM_API_KEY=
|
|
||||||
LLM_BASE_URL=https://api.openai.com/v1
|
|
||||||
LLM_MODEL=gpt-4o
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# Логирование
|
|
||||||
# ======================================================================
|
|
||||||
ENABLE_BELIEF_STATE_LOGGING=true
|
|
||||||
TASK_LOG_LEVEL=INFO
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# Admin bootstrap (первый запуск)
|
|
||||||
# ======================================================================
|
|
||||||
INITIAL_ADMIN_CREATE=false
|
|
||||||
INITIAL_ADMIN_USERNAME=admin
|
|
||||||
INITIAL_ADMIN_PASSWORD=change-me
|
|
||||||
INITIAL_ADMIN_EMAIL=
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# CORS / Безопасность деплоя
|
|
||||||
# ======================================================================
|
|
||||||
ALLOWED_ORIGINS=http://localhost:8000
|
|
||||||
FORCE_HTTPS=false
|
|
||||||
APP_TIMEZONE=Europe/Moscow
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# Features
|
|
||||||
# ======================================================================
|
|
||||||
FEATURES__DATASET_REVIEW=true
|
|
||||||
FEATURES__HEALTH_MONITOR=true
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# Агент (опциональные тонкие настройки)
|
|
||||||
# ======================================================================
|
|
||||||
# GRADIO_ALLOW_PORT_FALLBACK=true
|
|
||||||
# AGENT_ENABLE_LLM_TITLES=true
|
|
||||||
# AGENT_TITLE_GENERATION_TIMEOUT_S=0.25
|
|
||||||
# AGENT_PREFETCH_DASHBOARD_LIMIT=25
|
|
||||||
# AGENT_CONFIRM_TOOLS=false
|
|
||||||
# AGENT_INTERRUPT_BEFORE=
|
|
||||||
|
|
||||||
# ======================================================================
|
|
||||||
# ADFS SSO (опционально)
|
|
||||||
# ======================================================================
|
|
||||||
# ADFS_CLIENT_ID=
|
|
||||||
# ADFS_CLIENT_SECRET=
|
|
||||||
# ADFS_METADATA_URL=
|
|
||||||
@@ -9,11 +9,17 @@ COMPOSE_PROJECT_NAME=ss-tools-current
|
|||||||
|
|
||||||
# ── PostgreSQL (встроенный, docker compose db service) ──────────────────
|
# ── PostgreSQL (встроенный, docker compose db service) ──────────────────
|
||||||
POSTGRES_IMAGE=postgres:16-alpine
|
POSTGRES_IMAGE=postgres:16-alpine
|
||||||
|
POSTGRES_HOST=db
|
||||||
|
POSTGRES_PORT=5432
|
||||||
POSTGRES_HOST_PORT=5433
|
POSTGRES_HOST_PORT=5433
|
||||||
POSTGRES_DB=ss_tools
|
POSTGRES_DB=ss_tools
|
||||||
POSTGRES_USER=postgres
|
POSTGRES_USER=postgres
|
||||||
POSTGRES_PASSWORD=postgres
|
POSTGRES_PASSWORD=postgres
|
||||||
|
|
||||||
|
# Universal one-shot migration reset. Legacy Alembic revisions are replaced
|
||||||
|
# by 0001_baseline; repeated starts preserve the baseline schema.
|
||||||
|
RESET_DATABASE_SCHEMA=false
|
||||||
|
|
||||||
# ── Application storage ─────────────────────────────────────────────────
|
# ── Application storage ─────────────────────────────────────────────────
|
||||||
STORAGE_ROOT_PATH=/app/storage
|
STORAGE_ROOT_PATH=/app/storage
|
||||||
|
|
||||||
@@ -63,6 +69,7 @@ GRADIO_SERVER_PORT=7860
|
|||||||
# ── Сертификаты / фронтенд ─────────────────────────────────────────────
|
# ── Сертификаты / фронтенд ─────────────────────────────────────────────
|
||||||
CERTS_PATH=./certs
|
CERTS_PATH=./certs
|
||||||
SSL_KEY_PASSPHRASE=
|
SSL_KEY_PASSPHRASE=
|
||||||
|
LLM_CA_CERT_URLS=
|
||||||
|
|
||||||
# ── Логирование ────────────────────────────────────────────────────────
|
# ── Логирование ────────────────────────────────────────────────────────
|
||||||
ENABLE_BELIEF_STATE_LOGGING=true
|
ENABLE_BELIEF_STATE_LOGGING=true
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ superset-tools/
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **current** | `.env.current` | `docker compose --profile current up --build` |
|
| **current** | `.env.current` | `docker compose --profile current up --build` |
|
||||||
| **master** | `.env.master` | `docker compose --profile master up --build` |
|
| **master** | `.env.master` | `docker compose --profile master up --build` |
|
||||||
| **enterprise-clean** | `.env.enterprise-clean` | `docker compose --profile enterprise-clean up --build` |
|
| **enterprise-clean** | `.env` | `docker compose -f docker-compose.enterprise-clean.yml up --build` |
|
||||||
| **e2e** | `.env.e2e` | `docker compose -f docker-compose.e2e.yml up --build` |
|
| **e2e** | `.env.e2e` | `docker compose -f docker-compose.e2e.yml up --build` |
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -353,7 +353,7 @@ scripts/diag_container.py --target your-llm-provider.com:443 # Контейне
|
|||||||
Разворот в корпоративной сети с очищенным дистрибутивом (без тестовых данных, запрет внешних источников, compliance-проверка):
|
Разворот в корпоративной сети с очищенным дистрибутивом (без тестовых данных, запрет внешних источников, compliance-проверка):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.enterprise-clean.example .env
|
cp .env.example .env
|
||||||
docker compose --profile enterprise-clean up --build
|
docker compose --profile enterprise-clean up --build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ def test_generated_enterprise_backend_requires_service_jwt() -> None:
|
|||||||
|
|
||||||
assert "SERVICE_JWT: \\${SERVICE_JWT:?Set SERVICE_JWT in .env}" in backend_block
|
assert "SERVICE_JWT: \\${SERVICE_JWT:?Set SERVICE_JWT in .env}" in backend_block
|
||||||
assert "RESET_DATABASE_SCHEMA: \\${RESET_DATABASE_SCHEMA:-true}" in backend_block
|
assert "RESET_DATABASE_SCHEMA: \\${RESET_DATABASE_SCHEMA:-true}" in backend_block
|
||||||
|
assert '"env_template": ".env.example"' in text
|
||||||
|
assert '${DIST_ROOT}/.env.example' in text
|
||||||
|
|
||||||
|
|
||||||
def test_generated_light_compose_requires_all_runtime_secrets() -> None:
|
def test_generated_light_compose_requires_all_runtime_secrets() -> None:
|
||||||
|
|||||||
20
build.sh
20
build.sh
@@ -75,7 +75,7 @@ setup_compose_profile() {
|
|||||||
COMPOSE_FILE="docker-compose.yml"
|
COMPOSE_FILE="docker-compose.yml"
|
||||||
;;
|
;;
|
||||||
enterprise-clean)
|
enterprise-clean)
|
||||||
PROFILE_ENV_FILE="$SCRIPT_DIR/.env.enterprise-clean"
|
PROFILE_ENV_FILE="$SCRIPT_DIR/.env"
|
||||||
PROJECT_NAME="superset-tools-enterprise"
|
PROJECT_NAME="superset-tools-enterprise"
|
||||||
COMPOSE_FILE="docker-compose.enterprise-clean.yml"
|
COMPOSE_FILE="docker-compose.enterprise-clean.yml"
|
||||||
;;
|
;;
|
||||||
@@ -567,7 +567,7 @@ postgres_image_id=${postgres_id}
|
|||||||
postgres_repo_digest=$(get_repo_digest "${postgres_tag}")
|
postgres_repo_digest=$(get_repo_digest "${postgres_tag}")
|
||||||
postgres_archive=superset-tools-postgres.${tag}${suffix}.tar.xz
|
postgres_archive=superset-tools-postgres.${tag}${suffix}.tar.xz
|
||||||
compose_file=docker-compose.enterprise-clean.yml
|
compose_file=docker-compose.enterprise-clean.yml
|
||||||
env_template=.env.enterprise-clean.example
|
env_template=.env.example
|
||||||
env_bootstrap_fields=INITIAL_ADMIN_CREATE,INITIAL_ADMIN_USERNAME,INITIAL_ADMIN_PASSWORD,INITIAL_ADMIN_EMAIL
|
env_bootstrap_fields=INITIAL_ADMIN_CREATE,INITIAL_ADMIN_USERNAME,INITIAL_ADMIN_PASSWORD,INITIAL_ADMIN_EMAIL
|
||||||
checksums_file=sha256sums.${tag}${suffix}.txt
|
checksums_file=sha256sums.${tag}${suffix}.txt
|
||||||
generated_at_utc=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
generated_at_utc=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
@@ -608,7 +608,7 @@ EOF
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"compose_file": "docker-compose.enterprise-clean.yml",
|
"compose_file": "docker-compose.enterprise-clean.yml",
|
||||||
"env_template": ".env.enterprise-clean.example",
|
"env_template": ".env.example",
|
||||||
"env_bootstrap_fields": [
|
"env_bootstrap_fields": [
|
||||||
"INITIAL_ADMIN_CREATE",
|
"INITIAL_ADMIN_CREATE",
|
||||||
"INITIAL_ADMIN_USERNAME",
|
"INITIAL_ADMIN_USERNAME",
|
||||||
@@ -626,7 +626,7 @@ EOF
|
|||||||
|
|
||||||
generate_bundle_env() {
|
generate_bundle_env() {
|
||||||
local tag="$1"
|
local tag="$1"
|
||||||
cat > "${DIST_ROOT}/.env.enterprise-clean.example" << 'ENV'
|
cat > "${DIST_ROOT}/.env.example" << 'ENV'
|
||||||
# #region env.enterprise-clean.bundle [C:2] [TYPE Module] [SEMANTICS env,docker,bundle]
|
# #region env.enterprise-clean.bundle [C:2] [TYPE Module] [SEMANTICS env,docker,bundle]
|
||||||
# @BRIEF Переменные окружения для docker-compose.enterprise-clean.yml (bundled postgres).
|
# @BRIEF Переменные окружения для docker-compose.enterprise-clean.yml (bundled postgres).
|
||||||
# Все образы предварительно загружены через xz -dc ... | docker load.
|
# Все образы предварительно загружены через xz -dc ... | docker load.
|
||||||
@@ -711,7 +711,7 @@ APP_TIMEZONE=Europe/Moscow
|
|||||||
FEATURES__DATASET_REVIEW=true
|
FEATURES__DATASET_REVIEW=true
|
||||||
FEATURES__HEALTH_MONITOR=true
|
FEATURES__HEALTH_MONITOR=true
|
||||||
ENV
|
ENV
|
||||||
echo "[bundle] ✅ Generated bundle env template: ${DIST_ROOT}/.env.enterprise-clean.example"
|
echo "[bundle] ✅ Generated bundle env template: ${DIST_ROOT}/.env.example"
|
||||||
}
|
}
|
||||||
|
|
||||||
bundle_release() {
|
bundle_release() {
|
||||||
@@ -770,8 +770,9 @@ bundle_release() {
|
|||||||
echo " xz -dc ${DIST_ROOT}/superset-tools-frontend.${tag}.tar.xz | docker load"
|
echo " xz -dc ${DIST_ROOT}/superset-tools-frontend.${tag}.tar.xz | docker load"
|
||||||
echo " xz -dc ${DIST_ROOT}/superset-tools-agent.${tag}.tar.xz | docker load"
|
echo " xz -dc ${DIST_ROOT}/superset-tools-agent.${tag}.tar.xz | docker load"
|
||||||
echo " xz -dc ${DIST_ROOT}/superset-tools-postgres.${tag}.tar.xz | docker load"
|
echo " xz -dc ${DIST_ROOT}/superset-tools-postgres.${tag}.tar.xz | docker load"
|
||||||
echo " # Edit .env.enterprise-clean.example -> .env.enterprise-clean, then:"
|
echo " # In the bundle directory, create and edit the standard Compose .env:"
|
||||||
echo " docker compose --env-file ${DIST_ROOT}/.env.enterprise-clean -f ${DIST_ROOT}/docker-compose.enterprise-clean.yml up -d"
|
echo " cd ${DIST_ROOT} && cp .env.example .env"
|
||||||
|
echo " docker compose -f docker-compose.enterprise-clean.yml up -d"
|
||||||
echo ""
|
echo ""
|
||||||
echo " NOTE: Bundle includes postgres container (db) — no external PostgreSQL needed."
|
echo " NOTE: Bundle includes postgres container (db) — no external PostgreSQL needed."
|
||||||
echo " Corporate certs: mount .crt files via CERTS_PATH=./certs (optional)."
|
echo " Corporate certs: mount .crt files via CERTS_PATH=./certs (optional)."
|
||||||
@@ -887,7 +888,7 @@ volumes:
|
|||||||
postgres_data:
|
postgres_data:
|
||||||
COMPOSE
|
COMPOSE
|
||||||
|
|
||||||
cp "${SCRIPT_DIR}/.env.enterprise-clean.example" "${DIST_ROOT}/.env.light.example"
|
cp "${SCRIPT_DIR}/.env.example" "${DIST_ROOT}/.env.light.example"
|
||||||
|
|
||||||
echo "[bundle:light] ✅ Lightweight bundle created in ${DIST_ROOT}"
|
echo "[bundle:light] ✅ Lightweight bundle created in ${DIST_ROOT}"
|
||||||
echo " # Load image:"
|
echo " # Load image:"
|
||||||
@@ -964,7 +965,8 @@ EOF
|
|||||||
echo " xz -dc ${DIST_ROOT}/superset-tools-frontend.${tag}${suffix}.tar.xz | docker load"
|
echo " xz -dc ${DIST_ROOT}/superset-tools-frontend.${tag}${suffix}.tar.xz | docker load"
|
||||||
echo " xz -dc ${DIST_ROOT}/superset-tools-agent.${tag}${suffix}.tar.xz | docker load"
|
echo " xz -dc ${DIST_ROOT}/superset-tools-agent.${tag}${suffix}.tar.xz | docker load"
|
||||||
echo " xz -dc ${DIST_ROOT}/superset-tools-postgres.${tag}${suffix}.tar.xz | docker load"
|
echo " xz -dc ${DIST_ROOT}/superset-tools-postgres.${tag}${suffix}.tar.xz | docker load"
|
||||||
echo " # Edit .env.enterprise-clean.example -> .env.enterprise-clean, then:"
|
echo " # In the bundle directory: cp .env.example .env, edit .env, then:"
|
||||||
|
echo " docker compose -f docker-compose.enterprise-clean.yml up -d"
|
||||||
echo " docker compose -f ${DIST_ROOT}/docker-compose.enterprise-clean.yml up -d"
|
echo " docker compose -f ${DIST_ROOT}/docker-compose.enterprise-clean.yml up -d"
|
||||||
echo ""
|
echo ""
|
||||||
echo " NOTE: Agent image includes sentence-transformers+torch (~500 MB+)."
|
echo " NOTE: Agent image includes sentence-transformers+torch (~500 MB+)."
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# #region docker.compose.enterprise-clean [C:4] [TYPE Module] [SEMANTICS docker,compose,enterprise]
|
# #region docker.compose.enterprise-clean [C:4] [TYPE Module] [SEMANTICS docker,compose,enterprise]
|
||||||
# @BRIEF Enterprise docker compose — сборка backend + frontend + agent из исходников,
|
# @BRIEF Enterprise docker compose — сборка backend + frontend + agent из исходников,
|
||||||
# встроенный Postgres (контейнер), корп. сертификаты.
|
# встроенный Postgres (контейнер), корп. сертификаты.
|
||||||
# @PRE Docker и docker compose установлены. Файлы .env.enterprise-clean настроены.
|
# @PRE Docker и docker compose установлены. Стандартный файл .env настроен.
|
||||||
# Postgres: запускается в контейнере (сервис db). Для внешнего PG — переопределить POSTGRES_HOST.
|
# Postgres: запускается в контейнере (сервис db). Для внешнего PG — переопределить POSTGRES_HOST.
|
||||||
# Сертификаты: опциональные .crt файлы в CERTS_PATH монтируются в /opt/certs.
|
# Сертификаты: опциональные .crt файлы в CERTS_PATH монтируются в /opt/certs.
|
||||||
# @POST Сервисы db, backend, frontend и agent запущены. SSL терминация в nginx опциональна.
|
# @POST Сервисы db, backend, frontend и agent запущены. SSL терминация в nginx опциональна.
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
# @RELATION DEPENDS_ON -> [docker/nginx.ssl.conf]
|
# @RELATION DEPENDS_ON -> [docker/nginx.ssl.conf]
|
||||||
# @RELATION DEPENDS_ON -> [docker/frontend.entrypoint.sh]
|
# @RELATION DEPENDS_ON -> [docker/frontend.entrypoint.sh]
|
||||||
# @RELATION DEPENDS_ON -> [docker/backend.entrypoint.sh]
|
# @RELATION DEPENDS_ON -> [docker/backend.entrypoint.sh]
|
||||||
# @DATA_CONTRACT Input: .env.enterprise-clean + ./certs/*.crt -> Output: запущенные контейнеры
|
# @DATA_CONTRACT Input: .env + ./certs/*.crt -> Output: запущенные контейнеры
|
||||||
# @INVARIANT При использовании встроенного postgres (сервис db) healthcheck гарантирует
|
# @INVARIANT При использовании встроенного postgres (сервис db) healthcheck гарантирует
|
||||||
# готовность БД через depends_on condition: service_healthy.
|
# готовность БД через depends_on condition: service_healthy.
|
||||||
# Для внешнего PG — переопределить POSTGRES_HOST и удалить сервис db.
|
# Для внешнего PG — переопределить POSTGRES_HOST и удалить сервис db.
|
||||||
@@ -41,7 +41,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: ${POSTGRES_DB:-ss_tools}
|
POSTGRES_DB: ${POSTGRES_DB:-ss_tools}
|
||||||
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
POSTGRES_USER: ${POSTGRES_USER:-postgres}
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
|
||||||
ports:
|
ports:
|
||||||
- "${POSTGRES_HOST_PORT:-5432}:5432"
|
- "${POSTGRES_HOST_PORT:-5432}:5432"
|
||||||
volumes:
|
volumes:
|
||||||
@@ -61,14 +61,14 @@ services:
|
|||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
environment:
|
environment:
|
||||||
DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
|
DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
|
||||||
STORAGE_ROOT_PATH: /app/storage
|
STORAGE_ROOT_PATH: /app/storage
|
||||||
# Safe one-shot default: legacy revisions are reset; 0001_baseline is preserved.
|
# Safe one-shot default: legacy revisions are reset; 0001_baseline is preserved.
|
||||||
RESET_DATABASE_SCHEMA: ${RESET_DATABASE_SCHEMA:-true}
|
RESET_DATABASE_SCHEMA: ${RESET_DATABASE_SCHEMA:-true}
|
||||||
BACKEND_PORT: 8000
|
BACKEND_PORT: 8000
|
||||||
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-}
|
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-}
|
||||||
AUTH_SECRET_KEY: ${AUTH_SECRET_KEY:?Set AUTH_SECRET_KEY in .env.enterprise-clean}
|
AUTH_SECRET_KEY: ${AUTH_SECRET_KEY:?Set AUTH_SECRET_KEY in .env}
|
||||||
ENCRYPTION_KEY: ${ENCRYPTION_KEY:?ENCRYPTION_KEY обязателен — сгенерируйте и укажите в .env.enterprise-clean}
|
ENCRYPTION_KEY: ${ENCRYPTION_KEY:?ENCRYPTION_KEY обязателен — сгенерируйте и укажите в .env}
|
||||||
ENABLE_BELIEF_STATE_LOGGING: ${ENABLE_BELIEF_STATE_LOGGING:-true}
|
ENABLE_BELIEF_STATE_LOGGING: ${ENABLE_BELIEF_STATE_LOGGING:-true}
|
||||||
TASK_LOG_LEVEL: ${TASK_LOG_LEVEL:-INFO}
|
TASK_LOG_LEVEL: ${TASK_LOG_LEVEL:-INFO}
|
||||||
INITIAL_ADMIN_CREATE: ${INITIAL_ADMIN_CREATE:-false}
|
INITIAL_ADMIN_CREATE: ${INITIAL_ADMIN_CREATE:-false}
|
||||||
@@ -129,9 +129,9 @@ services:
|
|||||||
LLM_MODEL: ${LLM_MODEL:-gpt-4o}
|
LLM_MODEL: ${LLM_MODEL:-gpt-4o}
|
||||||
FASTAPI_URL: http://backend:8000
|
FASTAPI_URL: http://backend:8000
|
||||||
CERTS_PATH: /opt/certs
|
CERTS_PATH: /opt/certs
|
||||||
AUTH_SECRET_KEY: ${AUTH_SECRET_KEY:?Set AUTH_SECRET_KEY in .env.enterprise-clean}
|
AUTH_SECRET_KEY: ${AUTH_SECRET_KEY:?Set AUTH_SECRET_KEY in .env}
|
||||||
SERVICE_JWT: ${SERVICE_JWT:?Set SERVICE_JWT in .env — do not use a public default for the service secret}
|
SERVICE_JWT: ${SERVICE_JWT:?Set SERVICE_JWT in .env — do not use a public default for the service secret}
|
||||||
DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env.enterprise-clean}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
|
DATABASE_URL: postgresql+psycopg2://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}@${POSTGRES_HOST:-db}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-ss_tools}
|
||||||
STORAGE_ROOT_PATH: /app/storage
|
STORAGE_ROOT_PATH: /app/storage
|
||||||
GRADIO_SERVER_PORT: 7860
|
GRADIO_SERVER_PORT: 7860
|
||||||
GRADIO_ROOT_PATH: /api/agent/gradio
|
GRADIO_ROOT_PATH: /api/agent/gradio
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ correctly building chains with intermediate CAs.
|
|||||||
docker cp scripts/check_llm_certs.py superset-tools-backend-1:/tmp/
|
docker cp scripts/check_llm_certs.py superset-tools-backend-1:/tmp/
|
||||||
|
|
||||||
docker compose -f docker-compose.enterprise-clean.yml \
|
docker compose -f docker-compose.enterprise-clean.yml \
|
||||||
--env-file .env.enterprise-clean exec backend \
|
exec backend \
|
||||||
python3 /tmp/check_llm_certs.py --target https://lite.ai.rusal.com
|
python3 /tmp/check_llm_certs.py --target https://lite.ai.rusal.com
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -255,15 +255,15 @@ ls ./certs/
|
|||||||
# RUSAL_ROOT.crt RGM_Issuing.crt UC_RUSAL_Policy_CA.crt etc.
|
# RUSAL_ROOT.crt RGM_Issuing.crt UC_RUSAL_Policy_CA.crt etc.
|
||||||
|
|
||||||
docker compose -f docker-compose.enterprise-clean.yml \
|
docker compose -f docker-compose.enterprise-clean.yml \
|
||||||
--env-file .env.enterprise-clean down
|
down
|
||||||
|
|
||||||
docker compose -f docker-compose.enterprise-clean.yml \
|
docker compose -f docker-compose.enterprise-clean.yml \
|
||||||
--env-file .env.enterprise-clean up -d
|
up -d
|
||||||
|
|
||||||
# Verify
|
# Verify
|
||||||
docker cp scripts/check_llm_certs.py superset-tools-backend-1:/tmp/
|
docker cp scripts/check_llm_certs.py superset-tools-backend-1:/tmp/
|
||||||
docker compose -f docker-compose.enterprise-clean.yml \
|
docker compose -f docker-compose.enterprise-clean.yml \
|
||||||
--env-file .env.enterprise-clean exec backend \
|
exec backend \
|
||||||
python3 /tmp/check_llm_certs.py --target https://lite.ai.rusal.com
|
python3 /tmp/check_llm_certs.py --target https://lite.ai.rusal.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ cd /home/busya/dev/superset-tools
|
|||||||
- `frontend` image с уже собранным SvelteKit bundle;
|
- `frontend` image с уже собранным SvelteKit bundle;
|
||||||
- `postgres` image или внутренний pinned base image;
|
- `postgres` image или внутренний pinned base image;
|
||||||
- `docker-compose.enterprise-clean.yml` для запуска в air-gapped окружении;
|
- `docker-compose.enterprise-clean.yml` для запуска в air-gapped окружении;
|
||||||
- `.env.enterprise-clean.example` с обязательными переменными;
|
- `.env.example` с обязательными переменными;
|
||||||
- manifest с версиями, sha256 и перечнем образов;
|
- manifest с версиями, sha256 и перечнем образов;
|
||||||
- инструкции по `docker load` / `docker compose up` без обращения к внешним registry.
|
- инструкции по `docker load` / `docker compose up` без обращения к внешним registry.
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ cd /home/busya/dev/superset-tools
|
|||||||
# backend.v1.0.0-rc2-docker.tar.xz
|
# backend.v1.0.0-rc2-docker.tar.xz
|
||||||
# frontend.v1.0.0-rc2-docker.tar.xz
|
# frontend.v1.0.0-rc2-docker.tar.xz
|
||||||
# postgres.v1.0.0-rc2-docker.tar.xz
|
# postgres.v1.0.0-rc2-docker.tar.xz
|
||||||
# manifest + sha256sums + docker-compose.enterprise-clean.yml + .env.enterprise-clean.example
|
# manifest + sha256sums + docker-compose.enterprise-clean.yml + .env.example
|
||||||
|
|
||||||
# 2. Передать dist/docker/* в изолированный контур
|
# 2. Передать dist/docker/* в изолированный контур
|
||||||
# 3. Импортировать образы локально (распаковка на лету)
|
# 3. Импортировать образы локально (распаковка на лету)
|
||||||
@@ -108,7 +108,8 @@ xz -dc dist/docker/frontend.v1.0.0-rc2-docker.tar.xz | docker load
|
|||||||
xz -dc dist/docker/postgres.v1.0.0-rc2-docker.tar.xz | docker load
|
xz -dc dist/docker/postgres.v1.0.0-rc2-docker.tar.xz | docker load
|
||||||
|
|
||||||
# 4. Подготовить env из шаблона
|
# 4. Подготовить env из шаблона
|
||||||
cp dist/docker/.env.enterprise-clean.example .env.enterprise-clean
|
cd dist/docker
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
# 4a. Для первого запуска задать bootstrap администратора
|
# 4a. Для первого запуска задать bootstrap администратора
|
||||||
# INITIAL_ADMIN_CREATE=true
|
# INITIAL_ADMIN_CREATE=true
|
||||||
@@ -116,7 +117,7 @@ cp dist/docker/.env.enterprise-clean.example .env.enterprise-clean
|
|||||||
# INITIAL_ADMIN_PASSWORD=<temporary-strong-secret>
|
# INITIAL_ADMIN_PASSWORD=<temporary-strong-secret>
|
||||||
|
|
||||||
# 5. Запустить только локальные образы
|
# 5. Запустить только локальные образы
|
||||||
docker compose --env-file .env.enterprise-clean -f dist/docker/docker-compose.enterprise-clean.yml up -d
|
docker compose -f docker-compose.enterprise-clean.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Для легковесного all-in-one образа (без Playwright, **~104 MB** вместо 575 MB):
|
Для легковесного all-in-one образа (без Playwright, **~104 MB** вместо 575 MB):
|
||||||
@@ -139,7 +140,7 @@ docker compose -f dist/docker/docker-compose.light.yml up
|
|||||||
Bootstrap администратора выполняется entrypoint-скриптом внутри backend container:
|
Bootstrap администратора выполняется entrypoint-скриптом внутри backend container:
|
||||||
- если `INITIAL_ADMIN_CREATE=true`, контейнер вызывает [`create_admin.py`](backend/src/scripts/create_admin.py) перед стартом API;
|
- если `INITIAL_ADMIN_CREATE=true`, контейнер вызывает [`create_admin.py`](backend/src/scripts/create_admin.py) перед стартом API;
|
||||||
- если администратор уже существует, учётная запись не меняется;
|
- если администратор уже существует, учётная запись не меняется;
|
||||||
- теги в [`.env.enterprise-clean.example`](.env.enterprise-clean.example) должны совпадать с фактически загруженными образами `superset-tools-backend:v1.0.0-rc2-docker` и `superset-tools-frontend:v1.0.0-rc2-docker`;
|
- runtime-параметры задаются стандартным Compose-файлом `.env` рядом с bundle compose;
|
||||||
- после первого входа пароль должен быть ротирован, а `INITIAL_ADMIN_CREATE` возвращён в `false`.
|
- после первого входа пароль должен быть ротирован, а `INITIAL_ADMIN_CREATE` возвращён в `false`.
|
||||||
|
|
||||||
Ограничения для production-grade offline release:
|
Ограничения для production-grade offline release:
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ cd /home/busya/dev/superset-tools
|
|||||||
- `sha256sums.v1.0.0-rc2-docker.txt`
|
- `sha256sums.v1.0.0-rc2-docker.txt`
|
||||||
- `manifest.v1.0.0-rc2-docker.{txt,json}`
|
- `manifest.v1.0.0-rc2-docker.{txt,json}`
|
||||||
- `docker-compose.enterprise-clean.yml`
|
- `docker-compose.enterprise-clean.yml`
|
||||||
- `.env.enterprise-clean.example`
|
- `.env.example`
|
||||||
|
|
||||||
Результат легковесного бандла:
|
Результат легковесного бандла:
|
||||||
- `superset-tools.v1.0.0.tar`
|
- `superset-tools.v1.0.0.tar`
|
||||||
@@ -200,7 +200,7 @@ docker load -i postgres.v1.0.0-rc2-docker.tar
|
|||||||
### 4. Подготовка конфигурации
|
### 4. Подготовка конфигурации
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.enterprise-clean.example .env.enterprise-clean
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
Минимально проверьте:
|
Минимально проверьте:
|
||||||
@@ -216,14 +216,14 @@ cp .env.enterprise-clean.example .env.enterprise-clean
|
|||||||
- `INITIAL_ADMIN_PASSWORD=<temporary-strong-secret>`
|
- `INITIAL_ADMIN_PASSWORD=<temporary-strong-secret>`
|
||||||
- `INITIAL_ADMIN_EMAIL=<optional>`
|
- `INITIAL_ADMIN_EMAIL=<optional>`
|
||||||
|
|
||||||
Также проверьте, что теги образов в [`.env.enterprise-clean`](.env.enterprise-clean.example) совпадают с реально загруженными:
|
Также проверьте, что теги образов в `.env` совпадают с реально загруженными:
|
||||||
- `BACKEND_IMAGE=superset-tools-backend:v1.0.0-rc2-docker`
|
- `BACKEND_IMAGE=superset-tools-backend:v1.0.0-rc2-docker`
|
||||||
- `FRONTEND_IMAGE=superset-tools-frontend:v1.0.0-rc2-docker`
|
- `FRONTEND_IMAGE=superset-tools-frontend:v1.0.0-rc2-docker`
|
||||||
|
|
||||||
### 5. Запуск в offline-контуре
|
### 5. Запуск в offline-контуре
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose --env-file .env.enterprise-clean -f docker-compose.enterprise-clean.yml up -d
|
docker compose -f docker-compose.enterprise-clean.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
Compose-файл использует `pull_policy: never`, поэтому runtime не должен обращаться к внешним registry.
|
Compose-файл использует `pull_policy: never`, поэтому runtime не должен обращаться к внешним registry.
|
||||||
@@ -239,7 +239,7 @@ Compose-файл использует `pull_policy: never`, поэтому runti
|
|||||||
После первого успешного входа обязательно:
|
После первого успешного входа обязательно:
|
||||||
- смените bootstrap-пароль на постоянный организационный секрет;
|
- смените bootstrap-пароль на постоянный организационный секрет;
|
||||||
- установите `INITIAL_ADMIN_CREATE=false`;
|
- установите `INITIAL_ADMIN_CREATE=false`;
|
||||||
- перезапустите stack с обновлённым `.env.enterprise-clean`.
|
- перезапустите stack с обновлённым `.env`.
|
||||||
|
|
||||||
Если bootstrap завершается ошибкой, backend не стартует — это ожидаемый fail-fast режим для безопасного ввода в эксплуатацию.
|
Если bootstrap завершается ошибкой, backend не стартует — это ожидаемый fail-fast режим для безопасного ввода в эксплуатацию.
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
# (fresh PostgreSQL, StartupEnvironmentWizard), так и "живой" проект с настроенными окружениями.
|
# (fresh PostgreSQL, StartupEnvironmentWizard), так и "живой" проект с настроенными окружениями.
|
||||||
# @REJECTED Использование одного docker-compose файла для обоих стейджей — enterprise-clean требует
|
# @REJECTED Использование одного docker-compose файла для обоих стейджей — enterprise-clean требует
|
||||||
# build из исходников + внешний PostgreSQL, а run.sh использует локальный dev compose.
|
# build из исходников + внешний PostgreSQL, а run.sh использует локальный dev compose.
|
||||||
# @DATA_CONTRACT Input: тег релиза (аргумент), .env.enterprise-clean.example, backend/.env
|
# @DATA_CONTRACT Input: тег релиза (аргумент), .env.example, backend/.env
|
||||||
# Output: dist/docker/*.tar.xz, dist/docker/manifest*.txt, playwright-report/
|
# Output: dist/docker/*.tar.xz, dist/docker/manifest*.txt, playwright-report/
|
||||||
# #endregion E2E.RunEnterpriseCleanE2E
|
# #endregion E2E.RunEnterpriseCleanE2E
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
- 1 TUI сценарий подготовки/проверки;
|
- 1 TUI сценарий подготовки/проверки;
|
||||||
- 6–9 новых/обновлённых модулей (+config_loader, filesystem_scanner, db_cleanup_executor);
|
- 6–9 новых/обновлённых модулей (+config_loader, filesystem_scanner, db_cleanup_executor);
|
||||||
- документация и контракты в пределах feature-папки;
|
- документация и контракты в пределах feature-папки;
|
||||||
- runtime bootstrap администратора через переменные `.env.enterprise-clean` без hardcode секретов в образах.
|
- runtime bootstrap администратора через стандартный Compose `.env` без hardcode секретов в образах.
|
||||||
|
|
||||||
## Constitution Check
|
## Constitution Check
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ frontend/
|
|||||||
## Implementation Traceability & Final Notes
|
## Implementation Traceability & Final Notes
|
||||||
|
|
||||||
- Статус реализации: Phase 1–7 завершены (T001–T044).
|
- Статус реализации: Phase 1–7 завершены (T001–T044).
|
||||||
- Новое расширение (post-release hardening, 2026-03-13): добавлен scope на управляемый bootstrap администратора через `.env.enterprise-clean` и docker startup flow.
|
- Новое расширение (post-release hardening, 2026-03-13): добавлен scope на управляемый bootstrap администратора через `.env` и docker startup flow.
|
||||||
- Ключевые подтверждения polish-фазы:
|
- Ключевые подтверждения polish-фазы:
|
||||||
- T039: smoke TUI сценария зафиксирован в [`quickstart.md`](./quickstart.md).
|
- T039: smoke TUI сценария зафиксирован в [`quickstart.md`](./quickstart.md).
|
||||||
- T040: контрактная проверка API подтверждена тестом [`backend/src/api/routes/__tests__/test_clean_release_api.py`](../../backend/src/api/routes/__tests__/test_clean_release_api.py).
|
- T040: контрактная проверка API подтверждена тестом [`backend/src/api/routes/__tests__/test_clean_release_api.py`](../../backend/src/api/routes/__tests__/test_clean_release_api.py).
|
||||||
@@ -179,12 +179,12 @@ frontend/
|
|||||||
|
|
||||||
Итог: базовая feature готова к финальному релизному циклу с обязательным CI gate (`COMPLIANT` only) и операционной доказательной базой для аудита.
|
Итог: базовая feature готова к финальному релизному циклу с обязательным CI gate (`COMPLIANT` only) и операционной доказательной базой для аудита.
|
||||||
|
|
||||||
## Post-Release Hardening Addendum — Admin Bootstrap via `.env.enterprise-clean`
|
## Post-Release Hardening Addendum — Admin Bootstrap via `.env`
|
||||||
|
|
||||||
Цель addendum: убрать ручной шаг создания initial admin после доставки offline bundle и сделать это управляемой частью container startup.
|
Цель addendum: убрать ручной шаг создания initial admin после доставки offline bundle и сделать это управляемой частью container startup.
|
||||||
|
|
||||||
Архитектурные решения:
|
Архитектурные решения:
|
||||||
1. В `.env.enterprise-clean.example` добавить параметры:
|
1. В `.env.example` добавить параметры:
|
||||||
- `INITIAL_ADMIN_CREATE=false` (default-safe),
|
- `INITIAL_ADMIN_CREATE=false` (default-safe),
|
||||||
- `INITIAL_ADMIN_USERNAME=admin`,
|
- `INITIAL_ADMIN_USERNAME=admin`,
|
||||||
- `INITIAL_ADMIN_PASSWORD=change-me`,
|
- `INITIAL_ADMIN_PASSWORD=change-me`,
|
||||||
@@ -195,7 +195,7 @@ frontend/
|
|||||||
- обрабатывает idempotency (существующий пользователь => без ошибки, лог `already exists`).
|
- обрабатывает idempotency (существующий пользователь => без ошибки, лог `already exists`).
|
||||||
3. В `docker-compose.enterprise-clean.yml` прокинуть переменные bootstrap администратора только в `backend` service.
|
3. В `docker-compose.enterprise-clean.yml` прокинуть переменные bootstrap администратора только в `backend` service.
|
||||||
4. В операционном runbook зафиксировать обязательную ротацию bootstrap-пароля после первого входа.
|
4. В операционном runbook зафиксировать обязательную ротацию bootstrap-пароля после первого входа.
|
||||||
5. В offline bundle manifest оставить ссылку на `.env.enterprise-clean.example` как source-of-truth для параметров запуска.
|
5. В offline bundle manifest оставить ссылку на `.env.example` как source-of-truth для параметров запуска.
|
||||||
|
|
||||||
Нефункциональные ограничения:
|
Нефункциональные ограничения:
|
||||||
- Никаких default production секретов в Git.
|
- Никаких default production секретов в Git.
|
||||||
|
|||||||
@@ -73,9 +73,9 @@ cd /home/busya/dev/superset-tools
|
|||||||
2. Повторно запустить проверку из того же TUI экрана (`F5`).
|
2. Повторно запустить проверку из того же TUI экрана (`F5`).
|
||||||
3. Повторять до статуса `COMPLIANT`.
|
3. Повторять до статуса `COMPLIANT`.
|
||||||
|
|
||||||
## Admin Bootstrap via `.env.enterprise-clean` (Docker Runtime)
|
## Admin Bootstrap via `.env` (Docker Runtime)
|
||||||
|
|
||||||
Для offline bundle deployment в контейнерах используйте runtime файл `.env.enterprise-clean` на базе шаблона `.env.enterprise-clean.example`.
|
Для offline bundle deployment в контейнерах используйте стандартный runtime файл `.env` на базе шаблона `.env.example`.
|
||||||
|
|
||||||
Обязательные параметры bootstrap:
|
Обязательные параметры bootstrap:
|
||||||
- `INITIAL_ADMIN_CREATE=true` для первого запуска;
|
- `INITIAL_ADMIN_CREATE=true` для первого запуска;
|
||||||
|
|||||||
@@ -102,9 +102,9 @@
|
|||||||
- **FR-018**: Стадия `NO_EXTERNAL_ENDPOINTS` MUST сканировать все текстовые файлы (включая код, конфиги, скрипты) на наличие URL/хостов и сверять каждый найденный endpoint с `allowed_sources`.
|
- **FR-018**: Стадия `NO_EXTERNAL_ENDPOINTS` MUST сканировать все текстовые файлы (включая код, конфиги, скрипты) на наличие URL/хостов и сверять каждый найденный endpoint с `allowed_sources`.
|
||||||
- **FR-019**: Процесс clean-подготовки MUST включать стадию очистки БД от тестовых пользователей и демо-данных. Правила очистки (таблицы, условия, исключения) задаются в секции `database_cleanup` файла `.clean-release.yaml`.
|
- **FR-019**: Процесс clean-подготовки MUST включать стадию очистки БД от тестовых пользователей и демо-данных. Правила очистки (таблицы, условия, исключения) задаются в секции `database_cleanup` файла `.clean-release.yaml`.
|
||||||
- **FR-020**: Структура `.clean-release.yaml` MUST включать секции: `profile`, `scan_mode`, `prohibited_categories`, `prohibited_paths`, `allowed_sources`, `ignore_paths`, `database_cleanup` (с подсекциями `tables` и `preserve`).
|
- **FR-020**: Структура `.clean-release.yaml` MUST включать секции: `profile`, `scan_mode`, `prohibited_categories`, `prohibited_paths`, `allowed_sources`, `ignore_paths`, `database_cleanup` (с подсекциями `tables` и `preserve`).
|
||||||
- **FR-021**: Enterprise clean release bundle MUST включать `.env.enterprise-clean.example` с параметрами bootstrap администратора (`INITIAL_ADMIN_USERNAME`, `INITIAL_ADMIN_PASSWORD`, `INITIAL_ADMIN_EMAIL` optional, `INITIAL_ADMIN_CREATE`) и безопасными комментариями по ротации пароля.
|
- **FR-021**: Enterprise clean release bundle MUST включать `.env.example` с параметрами bootstrap администратора (`INITIAL_ADMIN_USERNAME`, `INITIAL_ADMIN_PASSWORD`, `INITIAL_ADMIN_EMAIL` optional, `INITIAL_ADMIN_CREATE`) и безопасными комментариями по ротации пароля.
|
||||||
- **FR-022**: Docker startup flow backend MUST поддерживать idempotent bootstrap администратора при запуске контейнера: при `INITIAL_ADMIN_CREATE=true` система создаёт администратора только если пользователь отсутствует и не перезаписывает существующие credentials/roles.
|
- **FR-022**: Docker startup flow backend MUST поддерживать idempotent bootstrap администратора при запуске контейнера: при `INITIAL_ADMIN_CREATE=true` система создаёт администратора только если пользователь отсутствует и не перезаписывает существующие credentials/roles.
|
||||||
- **FR-023**: Процесс публикации clean bundle MUST включать операторский сценарий заполнения runtime `.env.enterprise-clean` из шаблона и подтверждение, что bootstrap-пароль заменён на организационный секрет до первого production запуска.
|
- **FR-023**: Процесс публикации clean bundle MUST включать операторский сценарий заполнения runtime `.env` из шаблона и подтверждение, что bootstrap-пароль заменён на организационный секрет до первого production запуска.
|
||||||
|
|
||||||
### Key Entities *(include if feature involves data)*
|
### Key Entities *(include if feature involves data)*
|
||||||
|
|
||||||
|
|||||||
@@ -143,9 +143,9 @@
|
|||||||
|
|
||||||
## Phase 8: Post-Release Hardening — Admin Bootstrap in Docker
|
## Phase 8: Post-Release Hardening — Admin Bootstrap in Docker
|
||||||
|
|
||||||
**Purpose**: Автоматизировать первичное создание администратора через runtime `.env.enterprise-clean` в offline/enterprise deployment.
|
**Purpose**: Автоматизировать первичное создание администратора через runtime `.env` в offline/enterprise deployment.
|
||||||
|
|
||||||
- [X] T045 Add admin bootstrap env contract to `.env.enterprise-clean.example` (`INITIAL_ADMIN_CREATE`, `INITIAL_ADMIN_USERNAME`, `INITIAL_ADMIN_PASSWORD`, optional `INITIAL_ADMIN_EMAIL`)
|
- [X] T045 Add admin bootstrap env contract to `.env.example` (`INITIAL_ADMIN_CREATE`, `INITIAL_ADMIN_USERNAME`, `INITIAL_ADMIN_PASSWORD`, optional `INITIAL_ADMIN_EMAIL`)
|
||||||
- [X] T046 Wire admin bootstrap envs to backend runtime in `docker-compose.enterprise-clean.yml`
|
- [X] T046 Wire admin bootstrap envs to backend runtime in `docker-compose.enterprise-clean.yml`
|
||||||
- [X] T047 Add backend entrypoint flow that performs idempotent admin bootstrap before app start in `docker/backend.Dockerfile` and new entrypoint script
|
- [X] T047 Add backend entrypoint flow that performs idempotent admin bootstrap before app start in `docker/backend.Dockerfile` and new entrypoint script
|
||||||
- [X] T048 Extend admin creation script for optional email and deterministic exit behavior for existing user in `backend/src/scripts/create_admin.py`
|
- [X] T048 Extend admin creation script for optional email and deterministic exit behavior for existing user in `backend/src/scripts/create_admin.py`
|
||||||
|
|||||||
Reference in New Issue
Block a user