Миграции базы данных

Master владеет схемой своей базы данных и поддерживает её в соответствии с запущенной версией.

При каждом запуске он выполняет Liquibase, чтобы применить изменения схемы, которые нужны текущей версии. Запускать миграции вручную не требуется.

Как выполняются миграции

Миграции — это часть запуска, а не отдельный шаг, который вы инициируете.

  • При каждом запуске. Прежде чем Master начнёт обслуживать UI и API, Liquibase проверяет базу данных и применяет недостающие changeset'ы.
  • В настроенной базе данных. Миграции выполняются на том же движке, который Master использует во время работы — SQLite, PostgreSQL или MySQL, выбираемом по префиксу JDBC URL. О том, как выбирается движок, см. раздел База данных.
  • Только один раз на изменение. Liquibase фиксирует каждый применённый changeset в своей служебной таблице (DATABASECHANGELOG). Уже применённый changeset пропускается, поэтому перезапуск Master безопасен и не затратен.
  • Быстрый отказ (fail-fast). Если миграцию применить невозможно, запуск прерывается с ошибкой, а не продолжается на наполовину мигрированной схеме.

Под какими учётными данными выполняются миграции

По умолчанию миграции используют те же учётные данные, с которыми подключается Master — axelix.master.database.username и axelix.master.database.password. Так как миграции создают и изменяют таблицы, этому пользователю базы данных нужны права на изменение схемы (DDL) в дополнение к правам на чтение и запись, которые Master использует во время работы.

Отдельный пользователь для миграций

Некоторые команды в повседневной работе запускают приложение под пользователем с минимальными правами, который может только читать и писать строки, а изменения схемы применяют под отдельным, более привилегированным пользователем. Master поддерживает такой сценарий двумя свойствами:

СвойствоЗначение по умолчаниюОписание
axelix.master.migrations.usernameaxelix.master.database.usernameПользователь, под которым Liquibase выполняет миграции. Нужны права на изменение схемы (DDL).
axelix.master.migrations.passwordaxelix.master.database.passwordПароль пользователя миграций.

Оба свойства по умолчанию принимают значение соответствующего свойства axelix.master.database.*. Если оставить их незаданными, миграции выполняются под тем же пользователем, что и остальное приложение — это описанное выше поведение. Когда вы их задаёте, Master подключается к той же базе данных — JDBC URL и драйвер из axelix.master.database.url используются повторно, — но аутентифицирует выполнение миграций под пользователем миграций. Всё после запуска по-прежнему работает под axelix.master.database.*.

В SQLite нет пользователей

SQLite хранит данные в локальном файле и не имеет понятия пользователя базы данных, поэтому axelix.master.migrations.* игнорируется, когда используется SQLite. Эти свойства применимы только к PostgreSQL и MySQL.

Как задать учётные данные миграций

Свойства миграций — это обычные настройки Master, поэтому они задаются так же, как и всё остальное. В примерах ниже используется PostgreSQL. С MySQL всё работает аналогично.

Запуск в виде JAR

Передайте их как системные свойства -D или укажите в файле конфигурации рядом с JAR.

axelix:
  master:
    database:
      url: jdbc:postgresql://db.internal:5432/axelix
      username: axelix_app        # пользователь времени выполнения (только DML)
      password: ${AXELIX_DB_PASSWORD}
    migrations:
      username: axelix_migrator    # пользователь миграций (DDL)
      password: ${AXELIX_MIGRATIONS_PASSWORD}

Или полностью в командной строке:

java \
  -Daxelix.master.database.url=jdbc:postgresql://db.internal:5432/axelix \
  -Daxelix.master.database.username=axelix_app \
  -Daxelix.master.database.password=... \
  -Daxelix.master.migrations.username=axelix_migrator \
  -Daxelix.master.migrations.password=... \
  -jar axelix-1.1.0.jar

Полную командную строку процесса может прочитать любой другой пользователь на хосте (ps -ef, /proc/<pid>/cmdline), поэтому пароли в форме с -D выше доступны каждому локальному процессу. Используйте её только для локальной пробы; для всего остального держите пароли в файле конфигурации, берущем значения из окружения (как в примере application.yaml выше), или передавайте их переменными окружения — см. Как безопасно передавать секреты.

Запуск в Docker

Образ автоматически применяет JAVA_TOOL_OPTIONS к JVM, поэтому это и есть способ передать свойства -D внутрь контейнера.

JAVA_TOOL_OPTIONS печатается целиком в stderr при старте (Picked up JAVA_TOOL_OPTIONS: ...), поэтому каждое значение -D в ней — включая пароли базы данных и миграций — попадает в docker logs и любой сборщик логов. Помещайте сюда только несекретные флаги -D, а пароли передавайте отдельными переменными окружения через -e (AXELIX_MASTER_DATABASE_PASSWORD, AXELIX_MASTER_MIGRATIONS_PASSWORD), которые связываются по тем же правилам нестрогого связывания. См. Как безопасно передавать секреты.

docker run --rm -p 8080:8080 \
  -e JAVA_TOOL_OPTIONS="\
    -Daxelix.master.database.url=jdbc:postgresql://db.internal:5432/axelix \
    -Daxelix.master.database.username=axelix_app \
    -Daxelix.master.database.password=... \
    -Daxelix.master.migrations.username=axelix_migrator \
    -Daxelix.master.migrations.password=..." \
  ghcr.io/axelixlabs/axelix:1.1.0

Запуск с Docker Compose

Добавьте свойства миграций в JAVA_TOOL_OPTIONS сервиса master, рядом с настройками базы данных.

docker-compose.yaml
services:
  master:
    image: ghcr.io/axelixlabs/axelix:1.1.0
    ports:
      - "8080:8080"
    environment:
      JAVA_TOOL_OPTIONS: >-
        -Daxelix.master.database.url=jdbc:postgresql://postgres:5432/axelix
        -Daxelix.master.database.username=${AXELIX_DB_USERNAME}
        -Daxelix.master.database.password=${AXELIX_DB_PASSWORD}
        -Daxelix.master.migrations.username=${AXELIX_MIGRATIONS_USERNAME}
        -Daxelix.master.migrations.password=${AXELIX_MIGRATIONS_PASSWORD}

Значения передайте через файл .env рядом с файлом Compose:

.env
AXELIX_DB_USERNAME=axelix_app
AXELIX_DB_PASSWORD=...
AXELIX_MIGRATIONS_USERNAME=axelix_migrator
AXELIX_MIGRATIONS_PASSWORD=...

Связанные материалы

  • Настройка Master — полный справочник свойств, включая настройки подключения axelix.master.database.*.

На этой странице