Files
SHiNE-server/deploy/POSTGRESQL_SERVERS_STANDARD.md
T

214 lines
8.7 KiB
Markdown
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.
# PostgreSQL для серверов SHiNE
Этот документ фиксирует целевой стандарт PostgreSQL, который должен использоваться на всех серверных контурах SHiNE после ухода от SQLite.
Пока это не текущий production-state, а согласованная целевая схема, под которую можно писать миграции, deploy-скрипты и server-конфиги.
## Цель
На каждом сервере SHiNE должна быть отдельная локальная PostgreSQL-база:
- запускается в Docker;
- использует `postgres:18`;
- хранит данные не внутри контейнера, а в примонтированной папке хоста;
- доступна только локально на сервере и из Docker-сети;
- не публикуется в интернет;
- автоматически перезапускается после reboot/crash;
- имеет healthcheck;
- использует отдельную БД приложения и отдельного пользователя приложения;
- пароли и секреты хранятся только в локальном `.env`/override-конфиге на сервере и не коммитятся в git.
## Базовый стандарт
- Версия PostgreSQL: `18.x`
- Docker image: `postgres:18`
- Имена по умолчанию:
- контейнер/сервис: `shine-postgres`
- база приложения: `shine_server_db`
- пользователь приложения: `shine_server`
- Политика перезапуска: `unless-stopped`
- Проверка готовности: `pg_isready`
## Сетевой доступ
PostgreSQL не должна быть доступна из интернета.
Разрешённые варианты:
- публиковать порт только на loopback:
- `127.0.0.1:5432:5432`
- либо не публиковать порт вообще, если клиент тоже живёт в Docker и ходит только по внутренней сети
Запрещено:
- `0.0.0.0:5432:5432`
- открытие `5432/tcp` через внешний firewall/NAT/public ingress
Рекомендация по умолчанию для SHiNE:
- использовать `127.0.0.1:5432:5432`
Это даёт:
- локальную диагностику через `psql` на самом сервере;
- отсутствие внешнего доступа из интернета;
- совместимость с приложением, если оно работает не в Docker.
## Хранение данных
Данные PostgreSQL должны храниться в локальной папке хоста, а не во внутреннем Docker volume контейнера.
Причины:
- проще бэкапить;
- проще переносить между серверами;
- проще контролировать место хранения;
- одинаковая схема для dev/test/production;
- ниже риск потерять данные при пересоздании контейнера.
Рекомендуемая схема каталогов на сервере:
Production:
```text
/home/player/SHiNE/postgres/shine_server_db
```
Test/devnet:
```text
/home/player/tX/postgres/shine_server_db
```
Если на одном сервере появится несколько баз SHiNE-сервисов, раскладывать их по отдельным каталогам:
```text
/home/player/SHiNE/postgres/shine_server_db
/home/player/SHiNE/postgres/analytics_db
/home/player/SHiNE/postgres/other_service_db
```
## Пользователи и права
Нужны два уровня доступа:
- системный `postgres` superuser для администрирования;
- рабочий пользователь приложения `shine_server` для подключения самого SHiNE server.
Требования:
- приложение не должно работать под `postgres`;
- `shine_server` не должен быть `superuser`;
- `shine_server` должен владеть своей БД `shine_server_db`;
- для миграций по умолчанию использовать пользователя приложения, если ему хватает прав;
- административные операции выполнять отдельно под `postgres`.
## Секреты
В git нельзя хранить:
- `.env` с реальными паролями;
- connection strings с паролями;
- SQL-файлы с зашитыми production/test паролями.
Хранить на сервере локально, например:
```text
/home/player/SHiNE/postgres/.env
```
или в другом root-only каталоге секретов хоста.
Минимально нужны:
- пароль `postgres`
- пароль `shine_server`
Допустимо, но не рекомендуется, временно использовать одинаковый пароль для локального dev. Для production и постоянных test-серверов лучше разные пароли.
## Пример целевого compose
Ниже пример целевой схемы, которую можно брать за основу для серверов:
```yaml
services:
shine-postgres:
image: postgres:18
container_name: shine-postgres
restart: unless-stopped
env_file:
- .env
environment:
POSTGRES_DB: ${POSTGRES_SUPERUSER_DB}
POSTGRES_USER: ${POSTGRES_SUPERUSER}
POSTGRES_PASSWORD: ${POSTGRES_SUPERUSER_PASSWORD}
PGDATA: /var/lib/postgresql/data/pgdata
ports:
- "127.0.0.1:5432:5432"
volumes:
- ${SHINE_POSTGRES_DATA_DIR}:/var/lib/postgresql/data
- ./initdb:/docker-entrypoint-initdb.d:ro
healthcheck:
test:
- CMD-SHELL
- pg_isready -U "$${POSTGRES_SUPERUSER}" -d "$${POSTGRES_SUPERUSER_DB}"
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
```
## Рекомендуемые переменные окружения
```dotenv
POSTGRES_SUPERUSER_DB=postgres
POSTGRES_SUPERUSER=postgres
POSTGRES_SUPERUSER_PASSWORD=change_me
SHINE_APP_DB=shine_server_db
SHINE_APP_USER=shine_server
SHINE_APP_PASSWORD=change_me_too
SHINE_POSTGRES_DATA_DIR=/home/player/SHiNE/postgres/shine_server_db
```
Для test/devnet путь адаптировать под конкретный контур:
```dotenv
SHINE_POSTGRES_DATA_DIR=/home/player/t2/postgres/shine_server_db
```
## Подключение приложения
SHiNE server должен подключаться именно к:
- host: `127.0.0.1`
- port: `5432`
- db: `shine_server_db`
- user: `shine_server`
Не подключать серверное приложение под `postgres`, кроме одноразовых административных операций вручную.
## Бэкапы
Так как данные лежат в bind-mount каталоге хоста, сама папка с данными должна попадать в серверную backup-стратегию.
Но для PostgreSQL предпочтителен не только файловый backup, а как минимум один из вариантов:
- регулярный `pg_dump`
- либо полноценный backup-скрипт с остановкой приложения/согласованным snapshot
Минимальное требование:
- перед серьёзными миграциями иметь свежий backup БД;
- перед production rollout новой серверной версии иметь проверяемый backup.
## Для будущей миграции SHiNE
При переводе SHiNE server с SQLite на PostgreSQL считать обязательным:
- сначала поднять PostgreSQL по этому стандарту;
- затем добавить серверные конфиги подключения;
- затем прогнать миграции схемы;
- только потом переключать runtime приложения на PostgreSQL.
До фактического rollout на конкретный сервер эта БД может ещё отсутствовать. Этот документ описывает не текущее наличие БД, а обязательный целевой стандарт для всех серверов SHiNE.