12-postgresql — PostgreSQL
☐ Опциональный. Реляционная СУБД: ставит сервер PostgreSQL, создаёт роль и базу для вашего приложения, кладёт пароль в
/root/.mitdev-credentials.
PostgreSQL — реляционная база данных (данные в таблицах, доступ по SQL). В термине встречаются:
роль — учётная запись внутри PostgreSQL (одновременно и «пользователь», и «группа»); WAL (write-ahead log) — журнал изменений, из которого работает репликация; connection string — одна строка вида postgresql://пользователь:пароль@хост:порт/база, по которой приложение подключается к БД.
Зачем нужен
Большинству веб-приложений (Node.js, PHP, Python, Go) нужна постоянная база данных. Этот модуль ставит PostgreSQL из репозитория дистрибутива и сразу готовит рабочую пару «роль + база» под ваш проект, чтобы приложению осталось только вписать строку подключения. Пароль генерируется автоматически (если вы не задали свой) и сохраняется в защищённый файл.
Когда включать и когда не нужен
- Включайте, если приложение хранит структурированные данные (пользователи, заказы, платежи), нужны транзакции, связи между таблицами, JSON-поля.
- Не нужен, если база живёт в Docker-контейнере вместе с приложением, если вы используете внешнюю облачную БД (RDS, Supabase, Neon) или если проекту хватает только кэша/очереди.
- На реплике кластера модуль ставить можно, но вопросы про имя базы и пароль установщик пропустит — данные приедут с primary через репликацию (см. раздел ниже).
Зависимости и требования
- Отдельных модулей-зависимостей нет — модуль самодостаточен.
- Поддерживаемые семейства ОС: Debian/Ubuntu (полная поддержка), RHEL/Rocky/Alma/Fedora (экспериментально). На RHEL кластер инициализируется явным
initdb. - Права root (установщик запускается через
sudo). - Достаточно места на диске под данные (
/var/lib/postgresqlна Debian,/var/lib/pgsqlна RHEL).
Что именно делает
Пошагово, функция module_install в modules/12-postgresql.sh:
- Ставит пакеты. На Debian/Ubuntu —
postgresqlиpostgresql-contrib. На RHEL —postgresql-serverиpostgresql-contrib, затем выполняетinitdb(на Debian кластер создаётся автоматически при установке пакета, на RHEL — нет). - Включает и запускает службу
postgresql(systemctl enable+restart). - Создаёт роль приложения с именем из
PG_APP_USER(по умолчанию — имя deploy-пользователя, обычноdeploy):- если роли ещё нет —
CREATE ROLE "<user>" WITH LOGIN CREATEDB PASSWORD '…'(правоCREATEDBпозволяет приложению самому создавать вспомогательные базы, например для тестов); - если роль уже есть и вы задали новый пароль —
ALTER ROLE "<user>" WITH LOGIN PASSWORD '…'(см. идемпотентность ниже); - если роль есть, а пароль не задан — пароль не трогается.
- если роли ещё нет —
- Создаёт базу данных с именем из
PG_APP_DB(по умолчаниюapp), владелец — роль приложения:createdb -O <user> <db>. Если база уже есть — пропускает. - Сохраняет учётные данные (
user,password,database) в/root/.mitdev-credentials. - Проверяет себя (
module_verify): служба активна иSELECT 1выполняется. Если нет — установка считается неуспешной.
Идемпотентность. Повторный запуск установщика безопасен: существующие роль и база не пересоздаются. Если при повторном запуске вы укажете новый пароль, он будет применён через ALTER ROLE (это штатный способ сменить пароль). Пустой пароль при повторном запуске существующей роли ничего не меняет.
На реплике кластера (модуль pgcluster, роль replica) установщик не задаёт вопросов про базу и пароль и не создаёт локальную роль/базу — иначе они были бы затёрты данными, приезжающими с primary.
Файлы, службы и порты
| Путь / юнит / порт | Назначение | Права / примечание |
|---|---|---|
Служба postgresql |
systemd-юнит СУБД | управляется systemctl, mitdev pg status |
Порт 5432/tcp |
приём подключений | по умолчанию слушает только 127.0.0.1 (localhost) |
/etc/postgresql/<версия>/main/ (Debian) |
конфигурация: postgresql.conf, pg_hba.conf |
владелец postgres |
/var/lib/postgresql/<версия>/main/ (Debian) |
данные кластера | владелец postgres, не трогать вручную |
/var/lib/pgsql/data/ (RHEL) |
конфигурация + данные | владелец postgres |
/var/log/postgresql/postgresql-<версия>-main.log (Debian) |
лог сервера | смотреть при проблемах запуска |
/root/.mitdev-credentials |
пароль роли приложения | 0600, только root |
Точную версию и путь на конкретном сервере покажет mitdev pg status.
Учётные данные
Пароль роли приложения хранится в /root/.mitdev-credentials (права 0600, читается только root). Посмотреть:
sudo grep '^postgresql:' /root/.mitdev-credentials
Пример вывода:
postgresql: user=deploy
postgresql: password=3f9c1a7b8e2d4056a1b9c8d7e6f5a4b3
postgresql: database=app
Если при установке вы оставили поле пароля пустым, mitdev сгенерировал случайный пароль (32 hex-символа) и записал его в этот файл — там же его и смотрите. Роль postgres (суперпользователь СУБД) пароля не имеет: локально к ней ходят через sudo -u postgres (аутентификация по системному пользователю, peer).
Настройка
| Переменная | Значения | По умолчанию | Влияние | Когда менять |
|---|---|---|---|---|
PG_APP_DB |
имя базы (латиница, цифры, _, не с цифры) |
app (POSTGRES_DB_DEFAULT) |
имя создаваемой базы | хотите осмысленное имя, например shop_prod |
PG_APP_USER |
имя роли | имя deploy-пользователя (deploy) |
имя создаваемой роли-владельца | нужен отдельный пользователь БД |
PG_APP_PASSWORD |
строка или пусто | пусто → сгенерировать | пароль роли | хотите задать свой пароль |
POSTGRES_DB_DEFAULT |
имя базы | app |
значение по умолчанию для вопроса про базу | меняете дефолт для всех установок |
Как переопределить настройки
Три способа (по возрастанию удобства):
- Вопросы установщика. При выборе модуля PostgreSQL установщик в разделе «База данных проекта» спросит имя базы (
PG_APP_DB), пользователя (PG_APP_USER) и пароль (PG_APP_PASSWORD; пусто — сгенерировать). Это штатный путь. - Экспорт переменных перед запуском (флаг
-Eобязателен, чтобыsudoсохранил переменные окружения):export PG_APP_DB=shop_prod export PG_APP_USER=shop export PG_APP_PASSWORD='моя-надёжная-строка' sudo -E ./install.sh - Правка дефолта
config/defaults.conf(POSTGRES_DB_DEFAULT="app") — меняет значение по умолчанию для всех будущих установок.
Как подключиться
Из приложения на этом же сервере (самый частый случай) — строка подключения через localhost:
postgresql://<user>:<password>@127.0.0.1:5432/<db>
Например для .env:
DATABASE_URL=postgresql://deploy:[email protected]:5432/app
Из командной строки как суперпользователь (администрирование, локально):
sudo -u postgres psql # интерактивная консоль
sudo -u postgres psql -d app # сразу в базу app
Из командной строки как роль приложения (проверить, что пароль верный):
psql "postgresql://deploy:ПАРОЛЬ@127.0.0.1:5432/app" -c "SELECT current_user, current_database();"
С другого сервера (сервер приложений отдельно от БД). По умолчанию 5432 закрыт для внешнего мира — так и должно быть. Правильный путь:
- Соберите приватную сеть между серверами:
mitdev net create/join(см. MESH.md). - На сервере БД разрешите доступ конкретному IP:
sudo mitdev pg allow <ip-сервера-приложений>— команда добавит правило вpg_hba.conf(только по TLS) и откроет порт в файрволе. - Приложение подключается по приватному IP с
?sslmode=require.
Никогда не открывайте 5432 в 0.0.0.0 «на весь интернет» — используйте mitdev pg allow и приватную сеть.
Проверка, что всё работает
Автоматическая проверка модуля (module_verify): служба активна и проходит SELECT 1. Вручную:
mitdev pg status
Ожидаемо: роль primary (read-write), служба «активна», список баз с размерами, среди них ваша база.
sudo -u postgres psql -tAc "SELECT 1"
Ожидаемо: 1.
sudo -u postgres psql -tAc "SELECT rolname FROM pg_roles WHERE rolname='deploy'"
sudo -u postgres psql -tAc "SELECT datname FROM pg_database WHERE datname='app'"
Ожидаемо: в каждом случае печатается имя (роль и база существуют).
mitdev doctor --deep
В разделе функциональных проб: PostgreSQL — принимает подключения (SELECT 1).
Типовые задачи
Создать ещё одну базу (владелец — роль приложения):
sudo -u postgres createdb -O deploy analytics
Создать ещё одну роль (пользователя) с паролем:
sudo -u postgres psql -c "CREATE ROLE reporter WITH LOGIN PASSWORD 'парольReporter'"
sudo -u postgres psql -c "GRANT CONNECT ON DATABASE app TO reporter"
Сменить пароль существующей роли:
sudo -u postgres psql -c "ALTER ROLE deploy WITH PASSWORD 'новый-пароль'"
После этого обновите пароль в .env приложения и (по желанию) в /root/.mitdev-credentials.
Резервная копия одной базы (дамп в файл):
sudo -u postgres pg_dump -Fc app > /root/app-$(date +%F).dump # компактный формат
sudo -u postgres pg_dumpall > /root/all-$(date +%F).sql # все базы + роли
Или общий бэкап всего сервера: sudo mitdev backup (включает pg_dumpall).
Восстановление / импорт бекапа проекта — используйте mitdev pg import (сам определит формат: .dump, .sql, .sql.gz, pg_dumpall):
sudo mitdev pg import /root/app-2026-07-10.dump app
Посмотреть активные соединения:
sudo -u postgres psql -c "SELECT pid, usename, datname, state, query FROM pg_stat_activity WHERE state <> 'idle'"
Размер базы и таблиц:
sudo -u postgres psql -d app -c "SELECT pg_size_pretty(pg_database_size('app'))"
Масштабирование и отказоустойчивость
Один сервер PostgreSQL — единая точка отказа. Для отказоустойчивости mitdev предлагает потоковую репликацию (streaming replication) и автоматический failover:
- Реплики и авто-failover — модуль
pgcluster, см. 18-postgresql-cluster.md. Primary принимает записи, реплики держат копию через WAL, watchdog повышает реплику при отказе primary. - Единый адрес кластера (виртуальный IP) — модуль
pgvip, см. 19-pg-vip.md: приложение всегда подключается по одному адресу, VIP автоматически «переезжает» на текущий primary. - Управление:
mitdev pg add-replica <ip>,mitdev pg replication,mitdev pg promote,mitdev pg allow <ip>, а для узлов в разных дата-центрах —mitdev pg proxy(локальный HAProxy). Подробности — HA.md и COMMANDS.md.
Частые ошибки
Симптом: приложение не может подключиться, password authentication failed.
Причина: неверный пароль в строке подключения.
Решение: сверьте пароль — sudo grep '^postgresql: password' /root/.mitdev-credentials; при необходимости пересоздайте: sudo -u postgres psql -c "ALTER ROLE deploy WITH PASSWORD '…'".
Симптом: could not connect to server: Connection refused на порту 5432 с другого сервера.
Причина: PostgreSQL слушает только localhost / доступ IP не открыт.
Решение: sudo mitdev pg allow <ip> на сервере БД + приватная сеть (mitdev net); проверьте файрвол провайдера.
Симптом: служба не стартует после установки.
Причина: конфликт кластера/повреждённые данные/занятый порт.
Решение: смотрите лог — journalctl -u postgresql -n 50 и /var/log/postgresql/postgresql-*-main.log.
Симптом: mitdev pg import жалуется «Это replica (read-only)».
Причина: импорт запущен на реплике.
Решение: импортируйте на primary — реплики получат данные автоматически через репликацию.
Симптом: role "deploy" already exists при повторной установке.
Причина: это не ошибка — модуль идемпотентен и просто пропускает создание существующей роли.
Решение: ничего делать не нужно; чтобы сменить пароль — задайте PG_APP_PASSWORD и запустите установщик повторно.
Откат и удаление
- Автоматический откат (
module_rollback) срабатывает, если установка модуля падает на середине: отключает и удаляет пакеты; созданные в этом запуске роль и база откатываются зарегистрированными undo-действиями (DROP ROLE/dropdb). - Ручное удаление:
Безsudo mitdev remove postgresql # снести пакеты, ДАННЫЕ СОХРАНИТЬ sudo mitdev remove postgresql --purge # снести всё, включая данные, роль и базу--purgeданные кластера (/var/lib/postgresql) сохраняются — пакеты удаляются, данные остаются для переустановки. С--purgeудаляются роль и база приложения, а затем стираются все данные кластера — необратимо. - Если узел участвовал в потоковой репликации, оверлей кластера (watchdog, эндпоинт роли, правила файрвола) снимается автоматически перед удалением.
См. также
- 18-postgresql-cluster.md — репликация и авто-failover
- 19-pg-vip.md — единый виртуальный IP кластера
- COMMANDS.md — команды
mitdev pg …(status, replication, allow, proxy, import) - HA.md — отказоустойчивость
- SECURITY.md — безопасность и учётные данные
- MESH.md — приватная сеть между серверами