Any language¶
Migrax isn't only for Java. Any application that keeps its database changes as SQL files can use it to apply them: Python, Node.js, Go, .NET, PHP, Ruby or anything else. You write the migrations; Migrax runs them once and in order, records them, and refuses to run a file that changed after it was applied. You don't need a second migration tool next to your framework.
| What you get | |
|---|---|
| Numbered migrations, applied once and in order | 0001_create_customer.sql, 0002_add_email.sql |
| Repeatable migrations for views and functions | R__customer_view.sql, run again when they change |
| A history table, checksums and a lock | Safe with several instances starting at the same time |
| Rollback scripts | rollback/0002_add_email.sql, run by migrax rollback |
| Checks before anything runs | migrax lint finds statements that lock tables or lose data |
| A status overview | migrax status, also as JSON for scripts |
The commands that compare the database with Java entities (generate, check, drift and
verify) have nothing to read in such a project; everything else works the same.
Two ways to run it¶
| Needs | Best for | |
|---|---|---|
| Container image | Docker | Docker Compose, Kubernetes, CI. Drivers for PostgreSQL, MariaDB, SQL Server, SQLite and H2 included |
| Command line | Java 17 or newer | Running it on your machine like any other development tool |
In three steps¶
-
Put your SQL files in a folder, for example
db/migrations: -
Tell Migrax the database, as a JDBC URL:
-
Apply the migrations:
docker run --rm --network host \ -v "$PWD/db/migrations:/migrations:ro" \ -e MIGRAX_DATABASE_URL \ -e MIGRAX_DATABASE_USER \ -e MIGRAX_DATABASE_PASSWORD \ ghcr.io/fsmutimeer/migrax:0.17.1 migrateThe image reads the migrations from
/migrations, soMIGRAX_LOCATIONSisn't needed there.$ migrax migrate Applying migration '0001_create_customer.sql'... Successfully applied migration '0001_create_customer.sql'. Applied 1 migration(s); 1 total in db/migrations.The command line also needs the database's JDBC driver: see Drivers.
Before your application starts¶
With Docker Compose, run Migrax as a service of its own and start the application only after it finished:
services:
db:
image: postgres:17
environment:
POSTGRES_DB: shop
POSTGRES_USER: shop
POSTGRES_PASSWORD: secret
healthcheck:
test: ["CMD-SHELL", "pg_isready -U shop -d shop"]
interval: 2s
retries: 30
migrate:
image: ghcr.io/fsmutimeer/migrax:0.17.1
command: migrate --lock-timeout 2m
volumes:
- ./db/migrations:/migrations:ro
environment:
MIGRAX_DATABASE_URL: jdbc:postgresql://db:5432/shop
MIGRAX_DATABASE_USER: shop
MIGRAX_DATABASE_PASSWORD: secret
depends_on:
db:
condition: service_healthy
app:
build: .
depends_on:
migrate:
condition: service_completed_successfully
When a migration fails, migrate exits with code 1 and the application doesn't start. In
Kubernetes, the same image runs as an init container or a Job: see
Containers and Kubernetes.
From your project's scripts¶
Call Migrax from the task runner your project already has, so everyone runs the same command:
Settings in environment variables (or a .env file your shell loads) keep these scripts free of
passwords. Every setting is listed in Configuration.
In CI¶
Check the migrations on every pull request, before they reach a database:
lint needs no database; migrate --dry-run connects and shows what would run. More in
Continuous integration.
Next¶
- SQL migrations for any language: drivers, writing
migrations, a database that already has tables, rollbacks and
migrax doctor, step by step. - Moving existing migrations to Migrax, when your project already has a history of applied migrations.
- Advanced migrations: placeholders, callbacks, environments and preconditions.