Перейти к содержанию

PostgreSQL

PostgreSQL — основная реляционная база данных DataHUB. Хранит метаданные платформы, конфигурацию обмена и состояние клиентов. Входит в поставку как отдельный Docker Compose блок и не требует развертывания внешней СУБД.

Эта статья описывает конфигурацию блока postgres, схему хранения данных и порядок обслуживания. Установка по шагам — в Быстром старте. Применение схемы — отдельным блоком Flyway (см. ниже).

Версия и образ

Образ PostgreSQL поставляется вендором и собран на базе официального postgres:17.6. В отличие от стандартного образа, в него добавлен HEALTHCHECK на основе pg_isready:

FROM postgres:17.6
HEALTHCHECK --interval=10s --timeout=5s --start-period=5s --retries=5 \
    CMD pg_isready || exit 1

Это позволяет Docker корректно отслеживать готовность БД и автоматически отмечать контейнер как unhealthy при недоступности.

Структура блока

Каталог блока — /etc/datahub/postgres/:

/etc/datahub/postgres/
├── docker-compose.yml   # описание контейнера
├── .env.template        # шаблон переменных окружения
├── .env                 # реальные значения (создаётся при установке)
└── data/                # данные БД (bind-mount в контейнер)

Файл docker-compose.yml (фактическое содержимое поставки):

services:
  postgres:
    image: registry.gitlab.com/datahub/v3/services/postgres:dev
    hostname: postgres
    container_name: postgres
    restart: always
    volumes:
      - ./data:/var/lib/postgresql/data:rw
    expose:
      - 5432
    env_file:
      - .env
    networks:
      - dh_network

Ключевые особенности:

  • expose: 5432 без ports — порт виден только внутри Docker-сети dh_network. Прямого доступа с хоста или из внешней сети нет.
  • ./data:/var/lib/postgresql/data:rw — все данные БД хранятся на хост-файловой системе в /etc/datahub/postgres/data/. При обновлении и пересоздании контейнера данные сохраняются.
  • hostname: postgres — DNS-имя внутри сети, по которому к БД обращаются backend и flyway.

Конфигурация (.env)

Шаблон .env.template:

POSTGRES_USER={{POSTGRES_USER}}
POSTGRES_PASSWORD={{POSTGRES_PASSWORD}}
POSTGRES_DB=DataHUB
POSTGRES_PORT=5432
Переменная Назначение Значение по умолчанию
POSTGRES_USER Имя суперпользователя БД, создаётся при первом старте контейнера задаётся вручную
POSTGRES_PASSWORD Пароль суперпользователя задаётся вручную, минимум 16 символов
POSTGRES_DB Имя основной базы платформы, создаётся при первом старте DataHUB
POSTGRES_PORT Порт PostgreSQL внутри контейнера 5432

Значения POSTGRES_USER и POSTGRES_PASSWORD затем подставляются в .env блоков flyway и backend — они используют тот же аккаунт для миграций и подключения.

Смена пароля у уже инициализированной БД

Переменная POSTGRES_PASSWORD в .env блока postgres используется официальным образом postgres только при первичной инициализации БД. У уже созданного пользователя пароль через эту переменную не меняется — её правка после первого запуска ни на что не повлияет до полной переинсталляции PGDATA.

Корректная смена пароля у живой БД — двумя действиями: сначала ALTER USER внутри psql, затем синхронизация значения в .env блоков postgres, flyway и backend с перезапуском backend и flyway. Шаги:

sudo docker exec -it postgres psql -U "$POSTGRES_USER" -d DataHUB -c "ALTER USER datahub WITH PASSWORD 'new-password';"

Затем поправить POSTGRES_PASSWORD в трёх .env (postgres/, flyway/, backend/) и пересоздать backend (docker compose up -d --force-recreate).

Генерация криптостойкого пароля:

head -c 32 /dev/urandom | base64

Каталог данных

Каталог ./data соответствует /var/lib/postgresql/data внутри контейнера — стандартное место хранения данных PostgreSQL (PGDATA). При первом старте контейнер выполняет initdb, создаёт суперпользователя из POSTGRES_USER/POSTGRES_PASSWORD и базу POSTGRES_DB. После этого структура каталога не должна меняться руками — для всех операций используется psql или pg_dump/pg_restore.

Подготовка каталога перед первым стартом (в Быстром старте, п. 4.3):

mkdir -p ./data
sudo chown -R root:root ./data
sudo chmod -R 775 ./data

После старта контейнера внутри каталога появится содержимое PGDATA: base/, pg_wal/, pg_xact/, конфиги (postgresql.conf, pg_hba.conf) и т.п.

Миграции (Flyway)

Схему платформы развёртывает отдельный одноразовый контейнер flyway (блок /etc/datahub/flyway/). Он использует те же креды, что и postgres:

POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB_NAME=DataHUB
POSTGRES_USER={{POSTGRES_USER}}
POSTGRES_PASSWORD={{POSTGRES_PASSWORD}}

Контейнер flyway стартует, применяет все доступные миграции к базе DataHUB и завершается (restart: "no"). Сам backend в режиме prod миграции не выполняет — встроенный Flyway в Spring Boot выключен (spring.flyway.enabled: false), а Hibernate переведён в режим ddl-auto: none. Это разделение исключает гонку: схема всегда обновляется одним явным шагом до старта backend.

Порядок при обновлении версии платформы: остановить backend → запустить flyway (применит новые миграции) → запустить backend. См. Обновление платформы.

Подключение Сервера DataHUB

Backend подключается к PostgreSQL по JDBC через сервисное имя postgres в общей Docker-сети. Параметры пула (application.yml):

spring:
  datasource:
    url: jdbc:postgresql://${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}
    username: ${POSTGRES_USER}
    password: ${POSTGRES_PASSWORD}
    connection-timeout: 5000
    hikari:
      validation-timeout: 3000
      maximum-pool-size: 5
      minimum-idle: 1
Параметр Значение Назначение
maximum-pool-size 5 Максимум одновременно открытых соединений к БД на один экземпляр backend
minimum-idle 1 Минимум прогретых соединений в пуле
connection-timeout 5000 мс Сколько ждать выдачу свободного соединения из пула
validation-timeout 3000 мс Сколько ждать ответа на SELECT 1 при проверке живости соединения

При высоких нагрузках или при горизонтальном масштабировании backend размер пула корректируется через переменные окружения backend (см. Архитектура / Масштабирование).

Hibernate настроен в режиме без автоматических изменений схемы:

spring:
  jpa:
    hibernate:
      ddl-auto: none
    open-in-view: false

ddl-auto: none означает: схема в БД всегда соответствует тому, что наложил Flyway, и backend никогда не вносит изменения сам.

Healthcheck и состояние

Healthcheck в образе вызывает pg_isready каждые 10 секунд. Проверка статуса контейнера:

sudo docker ps --filter name=postgres --format "table {{.Names}}\t{{.Status}}"

В колонке STATUS должно быть Up <время> (healthy). Состояние unhealthy указывает на то, что БД не отвечает — типичные причины: неверный пароль в .env, повреждённый PGDATA, переполнение диска.

Журнал контейнера:

sudo docker logs -f --tail 200 postgres

Доступ для администрирования

Прямого доступа к PostgreSQL снаружи нет. Для административных операций предусмотрены три способа:

1. Через pgAdmin (опциональный блок). Веб-интерфейс на хосте, проксируется через nginx по адресу https://lk.<your-domain>:15432/. Удобен для просмотра данных, выполнения ad-hoc запросов, импорта/экспорта. См. блок /etc/datahub/pg-agmin/.

2. Через psql внутри контейнера. Полный консольный клиент, всегда доступен:

sudo docker exec -it postgres psql -U "$POSTGRES_USER" -d DataHUB

(переменная POSTGRES_USER берётся из текущей оболочки или подставляется явно).

3. Через SSH-туннель. На время диагностики администратор может пробросить порт 5432 контейнера через SSH и подключиться к нему любым внешним клиентом. Постоянного проброса порта наружу — нет.

Резервное копирование

Логический бэкап одной командой (выполняется на сервере):

sudo docker exec -t postgres pg_dump -U "$POSTGRES_USER" -d DataHUB -F c -f /tmp/datahub-$(date +%F).dump

Извлечение дампа из контейнера на хост:

sudo docker cp postgres:/tmp/datahub-$(date +%F).dump /var/backups/datahub/

Восстановление в чистую БД:

sudo docker exec -i postgres pg_restore -U "$POSTGRES_USER" -d DataHUB --clean --if-exists < /var/backups/datahub/datahub-YYYY-MM-DD.dump

Полная стратегия бэкапа (расписание, ротация, репликация PGDATA) — в Резервном копировании.

Что дальше