# Внешняя PostgreSQL По умолчанию база работает в контейнере `postgres` из состава дистрибутива. Режим `external` отключает этот контейнер и подключает инстанс к вашей PostgreSQL — выделенному серверу, кластеру Patroni или пулеру соединений. Внешняя база нужна в двух случаях: когда СУБД в организации администрируется централизованно и когда строится [отказоустойчивая схема на двух нодах](ha.md) — там общая база обязательна. ## Что меняется | | Встроенная БД (`embedded`) | Внешняя БД (`external`) | | --- | --- | --- | | Контейнер `postgres` | Запускается, профиль compose `db` | Не запускается, профиль `db` не включается | | `POSTGRES_HOST` | `postgres` — имя сервиса в docker-сети | Ваш адрес: VIP, pgbouncer или endpoint Patroni | | Данные | `data/postgres/` в каталоге дистрибутива | На вашей стороне | | Резервное копирование | Дамп базы и файлы настроек — см. [«Резервное копирование и восстановление»](backup.md) | База — по правилам вашей СУБД; файлы настроек с сервера инстанса — см. [«Резервное копирование и восстановление»](backup.md) | Остальное не меняется: обращения к базе идут из контейнеров, поэтому адрес должен резолвиться и быть доступен **из контейнеров**, а не только с хоста. ## Требования к базе - PostgreSQL **15 или новее**. Установщик проверяет `server_version_num` и прерывается на более старой версии. - Отдельная база и роль. Права суперпользователя не нужны. - Роли требуются `CONNECT` на базу, `USAGE` и `CREATE` на схему (обычно `public`) и владение создаваемыми объектами: миграции Flyway создают таблицы от её имени. - Один адрес мастера. Список хостов в `POSTGRES_HOST` не поддерживается — используйте VIP, pgbouncer или endpoint Patroni. Пример подготовки: ```sql CREATE ROLE simple2fa LOGIN PASSWORD '…'; CREATE DATABASE simple2fa_local OWNER simple2fa; -- в созданной базе: GRANT CONNECT ON DATABASE simple2fa_local TO simple2fa; GRANT USAGE, CREATE ON SCHEMA public TO simple2fa; ``` ## Установка Режим задаётся при установке. В интерактивном режиме на вопросе о PostgreSQL укажите `external`, дальше установщик спросит адрес, порт, режим TLS и учётные данные. Неинтерактивно: ```bash ./install.sh --non-interactive \ --tls-mode none --host 10.0.0.5 \ --db-mode external \ --postgres-host pgvip.example.local \ --postgres-port 5432 \ --postgres-database simple2fa_local \ --postgres-user simple2fa \ --postgres-password '…' \ --generate-admin-password ``` Флаги режима БД: - **`--db-mode`** — `embedded` (по умолчанию) или `external`. - **`--postgres-host`** — обязателен для `external`. - **`--postgres-port`** — по умолчанию 5432. - **`--postgres-database`**, **`--postgres-user`**, **`--postgres-password`** — реквизиты подключения. - **`--postgres-ssl-mode`** — `disable` (по умолчанию), `require` или `verify-full`. - **`--postgres-ssl-ca`** — файл CA для `verify-full`; копируется в `certs/directory/postgres-ca.pem`. - **`--database-url`** — альтернатива отдельным параметрам: строка вида `postgres://user:pass@host:5432/db?sslmode=require`. Дискретные переменные при этом остаются — их использует панель. - **`--migrate`** — только применить миграции и выйти, без запуска стека. ### Предварительная проверка Перед запуском стека установщик подключается к базе одноразовым контейнером `postgres:16-alpine` и проверяет три вещи: 1. соединение с указанными реквизитами и режимом TLS; 2. версию сервера — не ниже 15; 3. право `CREATE` на текущей схеме. Если любая проверка не проходит, установка прерывается до того, как что-либо будет создано. ## TLS до базы | Режим | Поведение | | --- | --- | | `disable` | Без шифрования. По умолчанию | | `require` | Шифрование обязательно, сертификат сервера не проверяется | | `verify-full` | Шифрование и полная проверка сертификата по вашему CA | Файл CA помещается в `certs/directory/postgres-ca.pem` — туда же, где хранятся корневые сертификаты каталогов. Установщик копирует его сам, если передать `--postgres-ssl-ca`. Режим и путь применяются одинаково к `local-backend` и к панели администратора: обе части стека обращаются к базе с одинаковыми настройками TLS. !!! warning "Права на каталог сертификатов" `certs/directory` должен быть доступен на чтение непривилегированному пользователю контейнера — каталог `755`, файлы `644`. Иначе `local-backend` не прочитает CA и будет перезапускаться. ## Миграции Схему применяет одноразовый сервис `migrate` — тот же образ `local-backend`, запущенный с `APP_MIGRATE_ONLY`. Его запускают `install.sh` и `update.sh` до старта основных контейнеров. Шаг ограничен примерно 90 секундами: зависший контейнер снимается, и при необходимости схема применяется уже при старте `local-backend`. Flyway использует таблицу блокировок, поэтому одновременный старт двух нод на пустой базе безопасен — но при [обновлении нод](ha.md) их всё равно обновляют по одной. Применить миграции отдельно, не запуская стек: ```bash ./install.sh --migrate ``` ## Проверка `./doctor.sh` в режиме `external` проверяет: - доступность базы с указанными реквизитами; - версию не ниже 15 и право `CREATE`; - наличие таблицы `flyway_schema_history` — то есть что миграции хотя бы раз применялись; - маркерную таблицу схемы; - health-статус `local-backend` — если контейнер здоров, схема совместима с образом. Контейнер `postgres` при этом не ожидается, и его отсутствие ошибкой не считается. Типовые ошибки: | Строка `doctor.sh` | Причина | Действие | | --- | --- | --- | | `[FAIL] Внешняя PostgreSQL недоступна или права недостаточны` | Сеть, реквизиты, TLS или права роли | Проверить доступ из контейнеров, режим TLS и права `CONNECT`, `USAGE`, `CREATE` | | `[FAIL] Нет flyway_schema_history` | Миграции не применялись | `./install.sh --migrate` или `./update.sh` на одной ноде | | `[FAIL] Схема неполная` | Миграции применились не до конца | Смотреть `docker compose logs backend-local --tail 80` | !!! note "Имя сервиса backend" В командах `docker compose` сервис backend называется `backend-local`. В прежних версиях дистрибутива он назывался `local-backend`. Если команда отвечает `no such service: backend-local`, стенд ещё не обновлён — используйте прежнее имя или обновите стенд командой `./update.sh`. ## Смотрите также - [Установка локального инстанса](../local-instance.md) - [Отказоустойчивость на двух нодах](ha.md) - [Резервное копирование и восстановление](backup.md) - [Особые сценарии развёртывания](index.md)