12-postgresql — PostgreSQL

☐ Опциональный. Реляционная СУБД: ставит сервер PostgreSQL, создаёт роль и базу для вашего приложения, кладёт пароль в /root/.mitdev-credentials.

PostgreSQL — реляционная база данных (данные в таблицах, доступ по SQL). В термине встречаются: роль — учётная запись внутри PostgreSQL (одновременно и «пользователь», и «группа»); WAL (write-ahead log) — журнал изменений, из которого работает репликация; connection string — одна строка вида postgresql://пользователь:пароль@хост:порт/база, по которой приложение подключается к БД.

Зачем нужен

Большинству веб-приложений (Node.js, PHP, Python, Go) нужна постоянная база данных. Этот модуль ставит PostgreSQL из репозитория дистрибутива и сразу готовит рабочую пару «роль + база» под ваш проект, чтобы приложению осталось только вписать строку подключения. Пароль генерируется автоматически (если вы не задали свой) и сохраняется в защищённый файл.

Когда включать и когда не нужен

Зависимости и требования

Что именно делает

Пошагово, функция module_install в modules/12-postgresql.sh:

  1. Ставит пакеты. На Debian/Ubuntu — postgresql и postgresql-contrib. На RHEL — postgresql-server и postgresql-contrib, затем выполняет initdb (на Debian кластер создаётся автоматически при установке пакета, на RHEL — нет).
  2. Включает и запускает службу postgresql (systemctl enable + restart).
  3. Создаёт роль приложения с именем из PG_APP_USER (по умолчанию — имя deploy-пользователя, обычно deploy):
    • если роли ещё нет — CREATE ROLE "<user>" WITH LOGIN CREATEDB PASSWORD '…' (право CREATEDB позволяет приложению самому создавать вспомогательные базы, например для тестов);
    • если роль уже есть и вы задали новый пароль — ALTER ROLE "<user>" WITH LOGIN PASSWORD '…' (см. идемпотентность ниже);
    • если роль есть, а пароль не задан — пароль не трогается.
  4. Создаёт базу данных с именем из PG_APP_DB (по умолчанию app), владелец — роль приложения: createdb -O <user> <db>. Если база уже есть — пропускает.
  5. Сохраняет учётные данные (user, password, database) в /root/.mitdev-credentials.
  6. Проверяет себя (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 значение по умолчанию для вопроса про базу меняете дефолт для всех установок

Как переопределить настройки

Три способа (по возрастанию удобства):

  1. Вопросы установщика. При выборе модуля PostgreSQL установщик в разделе «База данных проекта» спросит имя базы (PG_APP_DB), пользователя (PG_APP_USER) и пароль (PG_APP_PASSWORD; пусто — сгенерировать). Это штатный путь.
  2. Экспорт переменных перед запуском (флаг -E обязателен, чтобы sudo сохранил переменные окружения):
    export PG_APP_DB=shop_prod
    export PG_APP_USER=shop
    export PG_APP_PASSWORD='моя-надёжная-строка'
    sudo -E ./install.sh
    
  3. Правка дефолта 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 закрыт для внешнего мира — так и должно быть. Правильный путь:

  1. Соберите приватную сеть между серверами: mitdev net create / join (см. MESH.md).
  2. На сервере БД разрешите доступ конкретному IP: sudo mitdev pg allow <ip-сервера-приложений> — команда добавит правило в pg_hba.conf (только по TLS) и откроет порт в файрволе.
  3. Приложение подключается по приватному 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:

Частые ошибки

Симптом: приложение не может подключиться, 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 и запустите установщик повторно.

Откат и удаление

См. также