diff --git a/.env.example b/.env.example index 3df4727..f0d7c03 100644 --- a/.env.example +++ b/.env.example @@ -2,13 +2,9 @@ # Скопируй в .env и заполни значения. Ключи вида Section__Key биндятся в IOptions ASP.NET Core. # ВСЕ значения-секреты ниже обязательно заменить перед запуском (особенно *_PASSWORD, *SigningKey). -# ── PostgreSQL (контейнер db) ───────────────────────────────────────────── -POSTGRES_DB=telewave -POSTGRES_USER=telewave -POSTGRES_PASSWORD=change-me-strong-db-password - -# Строка подключения приложения (host = имя сервиса БД в docker-compose) -ConnectionStrings__Default=Host=db;Port=5432;Database=telewave;Username=telewave;Password=change-me-strong-db-password +# ── PostgreSQL (внешний сервер, не в compose) ───────────────────────────── +# База и пользователь создаются заранее на самом сервере БД (см. README — раздел "Развёртывание"). +ConnectionStrings__Default=Host=10.10.1.134;Port=5432;Database=telewave;Username=telewave;Password=change-me-strong-db-password # ── JWT ─────────────────────────────────────────────────────────────────── Jwt__Issuer=TeleWave diff --git a/CLAUDE.md b/CLAUDE.md index 8452a7f..d91963f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -23,7 +23,8 @@ Маппинг DTO вручную. OpenAPI — нативный `Microsoft.AspNetCore.OpenApi` + Scalar UI. - **Frontend**: React 19 + Vite + TS, TanStack Query/Router, shadcn-стиль поверх Radix + Tailwind v4, Zustand (только auth+тема), react-hook-form + zod. pnpm, oxlint. -- **Инфра**: единый Docker-образ (API + статика SPA) + PostgreSQL в docker-compose. +- **Инфра**: единый Docker-образ (API + статика SPA); PostgreSQL — **внешний сервер**, не в + compose (в отличие от PnvPanel). ## Архитектура — жёсткие правила @@ -83,8 +84,11 @@ runtime. Никакого gosu/root-drop и Data Protection key-ring — секретов на диске пока нет (JWT-ключ — обычная конфигурация, не шифруемый секрет at-rest); если появятся зашифрованные данные (например API-ключи внешних сервисов) — добавлять Data Protection по образцу PnvPanel. -- docker-compose: `app` + `db` (PostgreSQL). Миграции применяются авто на старте - (`ApplyMigrationsAsync` в `Program.cs`). +- docker-compose: только `app` — PostgreSQL живёт вне compose (внешний сервер/хост, адрес и + креды — в `ConnectionStrings__Default` из `.env`; база и пользователь на нём создаются + заранее вручную, приложение их не сидит). Миграции применяются авто на старте + (`ApplyMigrationsAsync` в `Program.cs`) — прав `CREATEDB` не требуется, только DDL/DML в + уже существующей базе. - Не вводи отдельный nginx-контейнер для статики — ломает требование единого контейнера. - **TLS — внешний**; `app` отдаёт HTTP + доверяет `X-Forwarded-*` (`ForwardedHeaders`). @@ -121,7 +125,7 @@ pnpm lint && pnpm typecheck Инфраструктура: ```bash -docker compose up -d --build # api + postgres +docker compose up -d --build # только api; postgres — внешний, см. ConnectionStrings__Default ``` > Окружение: Windows, основная оболочка — **PowerShell**. Для POSIX-скриптов есть Bash-инструмент. diff --git a/README.md b/README.md index 873402d..678768c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ > Текущее состояние — **база**: вход/регистрация, роли, пользователи, минимальная админка, > приветственная главная страница. Каталог каналов и раздача видео — следующий этап, пока не > реализованы. Приложение (фронт + бек) поставляется **единым Docker-образом**; PostgreSQL — -> отдельным контейнером в compose. +> **внешний**, не поднимается через compose. ## Стек @@ -16,19 +16,28 @@ | БД | PostgreSQL (Npgsql) | | Auth | ASP.NET Core Identity + JWT (access + refresh, ротация) | | Frontend | React 19 + Vite + TypeScript, TanStack Query/Router, shadcn/ui + Tailwind v4 (ретро-CRT тема) | -| Упаковка | Единый Docker-образ (API + статика SPA) + PostgreSQL в docker-compose | +| Упаковка | Единый Docker-образ (API + статика SPA); PostgreSQL — внешний сервер | -## Быстрый старт +## Развёртывание -Единый Docker-образ + PostgreSQL: +Postgres не входит в compose — база и пользователь создаются заранее на внешнем сервере БД: + +```sql +-- на сервере БД (psql -h <хост БД> -U postgres) +CREATE USER telewave WITH PASSWORD 'change-me-strong-db-password'; +CREATE DATABASE telewave OWNER telewave; +``` + +Затем на хосте с приложением: ```bash -cp .env.example .env # заполнить AdminSeed__Password, Jwt__SigningKey и т.д. +cp .env.example .env +# заполнить ConnectionStrings__Default (хост/база/юзер/пароль БД), Jwt__SigningKey, AdminSeed__* docker compose up -d --build # → http://localhost:8085 (админ — логин/пароль из .env, AdminSeed__Username/Password) ``` -Локальная разработка (без Docker для приложения — только `db`): +## Локальная разработка ```bash # backend, из backend/ diff --git a/docker-compose.yml b/docker-compose.yml index a8d0428..aebbd0d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,39 +1,14 @@ services: - db: - image: postgres:17-alpine - environment: - POSTGRES_DB: ${POSTGRES_DB:-telewave} - POSTGRES_USER: ${POSTGRES_USER:-telewave} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-telewave} - volumes: - - pgdata:/var/lib/postgresql/data - healthcheck: - test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-telewave} -d ${POSTGRES_DB:-telewave}'] - interval: 5s - timeout: 5s - retries: 10 - restart: unless-stopped - logging: - driver: json-file - options: - max-size: '10m' - max-file: '3' - app: build: context: . dockerfile: Dockerfile - depends_on: - db: - condition: service_healthy - # Секреты (Jwt__SigningKey, AdminSeed__Password, ...) — из .env, см. .env.example. - # ConnectionStrings__Default ниже переопределяет .env: адрес БД внутри сети compose всегда 'db'. + # Postgres — внешний (не в compose), см. ConnectionStrings__Default в .env. env_file: - .env environment: ASPNETCORE_ENVIRONMENT: Production ASPNETCORE_HTTP_PORTS: '8085' - ConnectionStrings__Default: 'Host=db;Port=5432;Database=${POSTGRES_DB:-telewave};Username=${POSTGRES_USER:-telewave};Password=${POSTGRES_PASSWORD:-telewave}' healthcheck: test: ['CMD', 'curl', '-f', 'http://localhost:8085/health'] interval: 15s @@ -48,6 +23,3 @@ services: options: max-size: '10m' max-file: '3' - -volumes: - pgdata: