Skip to main content
The kratos migrate command provides tools for managing database schema migrations. Use these commands when installing Kratos for the first time or upgrading to a new version.
Always create a database backup before running migrations!Migrations modify your database schema and can’t be automatically reversed in all cases.

Commands

migrate sql

Create SQL schemas and apply migration plans.
kratos migrate sql <database-url> [flags]

Description

This command should be run:
  • On a fresh SQL installation (initial setup)
  • When upgrading Ory Kratos to a new minor version
  • Before starting Kratos with a new database
It’s recommended to run this command close to the SQL instance (e.g., same subnet) instead of over the public internet to decrease failure risk and time required.

Supported databases

Kratos supports the following SQL databases:
  • PostgreSQL 11+
  • MySQL 5.7+
  • SQLite (not recommended for production)
  • CockroachDB 20.1+

Flags

--read-from-env
boolean
default:"false"
Read database connection string from environment variable DSN or config file key dsn.Short flag: -e
--yes
boolean
default:"false"
Accept all confirmation prompts without user interaction.Short flag: -y
--config
string
Path to configuration file.

Database URL format

The database URL follows this format:
postgres://user:password@host:port/database?sslmode=disable

Examples

kratos migrate sql \
  postgres://kratos:secret@localhost:5432/kratos?sslmode=disable \
  --yes

Output example

Applying migrations...
Successfully applied 5 migrations:
  20210101000000_create_identities.sql
  20210102000000_create_sessions.sql
  20210103000000_create_recovery_addresses.sql
  20210104000000_create_verification_addresses.sql
  20210105000000_create_credentials.sql

Migrations completed successfully!

migrate sql up

Apply pending migrations to bring the database schema up to date.
kratos migrate sql up [database-url] [flags]

Description

This command applies all pending migrations to upgrade your database schema to the latest version.

Examples

kratos migrate sql up postgres://kratos:secret@localhost:5432/kratos --yes

migrate sql down

Rollback the most recent migration.
kratos migrate sql down [database-url] [flags]
Use with extreme caution!Rolling back migrations can result in data loss. Always backup your database first.

Description

This command rolls back the most recently applied migration. Use this if you need to downgrade Kratos or fix a migration issue.

Flags

--steps
integer
default:"1"
Number of migrations to roll back.
--read-from-env
boolean
Read database URL from environment variable DSN.Short flag: -e
--yes
boolean
Skip confirmation prompts.Short flag: -y

Examples

kratos migrate sql down postgres://kratos:secret@localhost:5432/kratos --yes

migrate sql status

Show the current migration status.
kratos migrate sql status [database-url] [flags]

Description

This command displays information about applied and pending migrations.

Examples

kratos migrate sql status postgres://kratos:secret@localhost:5432/kratos

Output example

Migration Status:

Applied migrations:
  20210101000000_create_identities.sql (applied: 2024-01-15 10:30:00)
  20210102000000_create_sessions.sql (applied: 2024-01-15 10:30:01)
  20210103000000_create_recovery_addresses.sql (applied: 2024-01-15 10:30:02)

Pending migrations:
  20210104000000_create_verification_addresses.sql
  20210105000000_create_credentials.sql

Database is 2 migrations behind.

Workflows

Initial setup

When setting up Kratos for the first time:
1

Create database

Create an empty database for Kratos:
CREATE DATABASE kratos;
CREATE USER kratos WITH PASSWORD 'secret';
GRANT ALL PRIVILEGES ON DATABASE kratos TO kratos;
2

Run migrations

Apply all migrations to initialize the schema:
kratos migrate sql \
  postgres://kratos:secret@localhost:5432/kratos \
  --yes
3

Verify migration

Check that all migrations were applied:
kratos migrate sql status \
  postgres://kratos:secret@localhost:5432/kratos
4

Start Kratos

Start the Kratos server:
kratos serve --config config.yml

Upgrading Kratos

When upgrading to a new version:
1

Backup database

Critical: Create a backup before upgrading!
# PostgreSQL
pg_dump -h localhost -U kratos kratos > backup.sql

# MySQL
mysqldump -u kratos -p kratos > backup.sql
2

Check migration status

See what migrations will be applied:
kratos migrate sql status postgres://kratos:secret@localhost:5432/kratos
3

Apply migrations

Run the migration:
kratos migrate sql up postgres://kratos:secret@localhost:5432/kratos --yes
4

Restart Kratos

Restart your Kratos instances with the new version.

CI/CD integration

Integrate migrations into your deployment pipeline:
name: Deploy Kratos

jobs:
  migrate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      
      - name: Install Kratos
        run: |
          bash <(curl https://raw.githubusercontent.com/ory/meta/master/install.sh) -b . kratos
          sudo mv ./kratos /usr/local/bin/
      
      - name: Run migrations
        env:
          DSN: ${{ secrets.DATABASE_URL }}
        run: |
          kratos migrate sql -e --yes
      
      - name: Deploy Kratos
        run: |
          # Your deployment commands here

Troubleshooting

Migration failed midway

If a migration fails partway through:
  1. Check the error message for details
  2. Check migration status: kratos migrate sql status <database-url>
  3. Fix the underlying issue (e.g., permissions, disk space)
  4. Re-run the migration: kratos migrate sql up <database-url> --yes

Locked database

If you see “database is locked” errors:
Error: database is locked
This usually means another migration is running. Wait for it to complete or check for stale locks in your database.

Permission denied

Error: permission denied for table schema_migration
Ensure the database user has sufficient permissions:
GRANT ALL PRIVILEGES ON DATABASE kratos TO kratos;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO kratos;

Connection refused

Error: dial tcp 127.0.0.1:5432: connect: connection refused
Check that:
  • Database is running
  • Connection string is correct
  • Network/firewall allows connection
  • Hostname and port are correct

Best practices

Always backup

Create a backup before every migration, especially in production.

Test first

Test migrations in a staging environment before running in production.

Check status

Use migrate sql status to review pending migrations before applying them.

Automate safely

Automate migrations in CI/CD, but always include proper error handling and rollback procedures.

See also

Build docs developers (and LLMs) love