# 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.