From d7743977a1a259fec8fe8012d969bb6c68695abf Mon Sep 17 00:00:00 2001 From: mrleo1nid <43583385+mrleo1nid@users.noreply.github.com> Date: Tue, 6 Oct 2026 19:45:17 +0300 Subject: [PATCH] Use bind mounts for pgdata and dp_keys in docker-compose Matches the production compose so the stack data lives next to the compose file and can be backed up with the server. ticket_uploads stays a named volume to avoid losing existing attachments on pull. Co-Authored-By: Claude Opus 5.5 --- .dockerignore | 5 +++++ .gitignore | 4 ++++ README.md | 7 ++++++- docker-compose.yml | 4 ++-- docs/architecture.md | 4 ++-- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/.dockerignore b/.dockerignore index 8654c63..c8826ac 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,6 +6,11 @@ **/node_modules/ frontend/dist/ +# Данные docker-compose (bind-маунты): в build context не нужны, а pgdata ещё и нечитаем +# (владелец — uid postgres), сборка на нём падала бы +pgdata/ +dp_keys/ + # VCS / IDE / env .git/ .vs/ diff --git a/.gitignore b/.gitignore index 66cf95a..df9fe5c 100644 --- a/.gitignore +++ b/.gitignore @@ -415,6 +415,10 @@ FodyWeavers.xsd *.sln.iml +# Данные docker-compose (bind-маунты) — БД и key-ring Data Protection +/pgdata/ +/dp_keys/ + # Local environment files (secrets) — keep .env.example, ignore real .env .env .env.local diff --git a/README.md b/README.md index 3a4c463..1dad1dd 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,14 @@ ```bash cp .env.example .env # заполнить AdminSeed__Password, Jwt__SigningKey и т.д. docker compose up -d --build -# → http://localhost:8080 (админ — логин/пароль из .env, AdminSeed__Username/Password) +# → http://localhost:8085 (админ — логин/пароль из .env, AdminSeed__Username/Password) ``` +БД и key-ring лежат рядом с `docker-compose.yml` (bind-маунты): `./pgdata` — PostgreSQL, `./dp_keys` — +key-ring Data Protection (без него не расшифровать пароли нод). Вложения тикетов и картинки — в +именованном volume `ticket_uploads`. Бэкап — остановить стек (`docker compose stop`) и скопировать +каталог целиком вместе с `.env` (+ содержимое volume `ticket_uploads`). + Локальная разработка (без Docker для приложения — только `db`): ```bash diff --git a/docker-compose.yml b/docker-compose.yml index dec4666..5331f3e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: POSTGRES_USER: ${POSTGRES_USER:-pnvpanel} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-pnvpanel} volumes: - - pgdata:/var/lib/postgresql/data + - ./pgdata:/var/lib/postgresql/data healthcheck: test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER:-pnvpanel} -d ${POSTGRES_DB:-pnvpanel}'] interval: 5s @@ -39,7 +39,7 @@ services: volumes: # Data Protection key-ring (шифрование секретов нод at-rest) должен пережить пересоздание # контейнера — иначе расшифровка паролей нод после рестарта станет невозможна. - - dp_keys:/app/keys + - ./dp_keys:/app/keys # Вложения тикетов поддержки (скриншоты) — обычные файлы на диске, см. DiskFileStorage. - ticket_uploads:/app/uploads healthcheck: diff --git a/docs/architecture.md b/docs/architecture.md index 1583ade..24436ea 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -97,11 +97,11 @@ PnvPanel — backend на **ASP.NET Core (.NET 10)** по принципам **C - **Background jobs**: `TrafficSyncService`, `NodeHealthCheckService`, `TrafficRetentionService`, `BillingService` (`BackgroundService` + `PeriodicTimer`). - **Secrets**: `DataProtectionSecretProtector : ISecretProtector` (шифрование паролей нод at-rest, - ASP.NET Core Data Protection, key-ring на томе `dp_keys`). + ASP.NET Core Data Protection, key-ring в bind-маунте `./dp_keys`). - **Telegram**: `TelegramNotifier : ITelegramNotifier` — отправка DM-уведомлений через `ITelegramBotClient`. - **Storage**: `DiskFileStorage : IFileStorage` — вложения тикетов поддержки и картинки для markdown (`MediaImage`), файлы на диске под GUID-именем (`FileStorage:RootPath`, том `ticket_uploads` в - docker-compose, как `dp_keys`). + docker-compose). > **SignalR-пуш физически лежит в `PnvPanel.Api/Hubs/`, не в `Infrastructure`.** > `SignalRRealtimeNotifier : IRealtimeNotifier` нужен `IHubContext`, а сам `PanelHub`