Dbmate
Dbmate is a database migration tool that will keep your database schema in sync across multiple developers and your production servers.
It is a standalone command line tool that can be used with Go, Node.js, Python, Ruby, PHP, Rust, C++, or any other language or framework you are using to write database-backed applications. This is especially helpful if you are writing multiple services in different languages, and want to maintain some sanity with consistent development tools.
For a comparison between dbmate and other popular database schema migration tools, please see Alternatives.
Table of Contents
Features
- Supports MySQL, MariaDB, PostgreSQL, SQLite, and ClickHouse
- Uses plain SQL for writing schema migrations
- Migrations are timestamp-versioned, to avoid version number conflicts with multiple developers
- Migrations are run atomically inside a transaction
- Supports creating and dropping databases (handy in development/test)
- Supports saving a
schema.sqlfile to easily diff schema changes in git - Database connection URL is defined using an environment variable (
DATABASE_URLby default), or specified on the command line - Built-in support for reading environment variables from your
.envfile - Easy to distribute, single self-contained binary
- Doesn't try to upsell you on a SaaS service
Installation
NPM
Install using NPM:
npm install --save-dev dbmate
npx dbmate --help
macOS
Install using Homebrew:
brew install dbmate
dbmate --help
Linux
Install the binary directly:
sudo curl -fsSL -o /usr/local/bin/dbmate https://github.com/amacneil/dbmate/releases/latest/download/dbmate-linux-amd64
sudo chmod +x /usr/local/bin/dbmate
/usr/local/bin/dbmate --help
Windows
Install using Scoop
scoop install dbmate
dbmate --help
Docker
Docker images are published to GitHub Container Registry (ghcr.io/amacneil/dbmate).
Remember to set --network=host or see this comment for more tips on using dbmate with docker networking):
docker run --rm -it --network=host ghcr.io/amacneil/dbmate --help
If you wish to create or apply migrations, you will need to use Docker's bind mount feature to make your local working directory (pwd) available inside the dbmate container:
docker run --rm -it --network=host -v "$(pwd)/db:/db" ghcr.io/amacneil/dbmate new create_users_table
Commands
dbmate --help # print usage help
dbmate new # generate a new migration file
dbmate up # create the database (if it does not already exist) and run any pending migrations
dbmate create # create the database
dbmate drop # drop the database
dbmate migrate # run any pending migrations
dbmate rollback # roll back the most recent migration
dbmate down # alias for rollback
dbmate status # show the status of all migrations (supports --exit-code and --quiet)
dbmate dump # write the database schema.sql file
dbmate dump -- [...] # optionally pass additional arguments directly to mysqldump or pg_dump
dbmate load # load schema.sql file to the database
dbmate wait # wait for the database server to become available
Command Line Options
The following options are available with all commands. You must use command line arguments in the order dbmate [global options] command [command options]. Most options can also be configured via environment variables (and loaded from your .env file, which is helpful to share configuration between team members).
--url, -u "protocol://host:port/dbname"- specify the database url directly. (env:DATABASE_URL)--driver "driver_name"- specify the driver to use (if empty, the driver is derived from database URL scheme). (env:DBMATE_DRIVER)--env, -e "DATABASE_URL"- specify an environment variable to read the database connection URL from.--env-file ".env"- specify an alternate environment variables file(s) to load.--migrations-dir, -d "./db/migrations"- where to keep the migration files. (env:DBMATE_MIGRATIONS_DIR)--migrations-table "schema_migrations"- database table to record migrations in. (env:DBMATE_MIGRATIONS_TABLE)--schema-file, -s "./db/schema.sql"- a path to keep the schema.sql file. (env:DBMATE_SCHEMA_FILE)--no-dump-schema- don't auto-update the schema.sql file on migrate/rollback (env:DBMATE_NO_DUMP_SCHEMA)--strict- fail if migrations would be applied out of order (env:DBMATE_STRICT)--wait- wait for the db to become available before executing the subsequent command (env:DBMATE_WAIT)--wait-timeout 60s- timeout for --wait flag (env:DBMATE_WAIT_TIMEOUT)--wait-interval 1s- time to wait between connection attempts for --wait flag (env:DBMATE_WAIT_INTERVAL)
Usage
Environment Variables
Most dbmate settings can be configured with environment variables in addition to command line flags. This is useful for twelve-factor style deployments and for sharing local configuration via a .env file.
Which settings use which environment variables
| Setting | Environment variable | Notes |
|---|---|---|
| Database URL | DATABASE_URL (default) |
Overridden by --url / -u. Use --env / -e to read the URL from a different variable (for example TEST_DATABASE_URL). |
| Driver | DBMATE_DRIVER |
Used when --driver is not set. |
| Migrations directory | DBMATE_MIGRATIONS_DIR |
Corresponds to --migrations-dir / -d. |
| Migrations table | DBMATE_MIGRATIONS_TABLE |
Corresponds to --migrations-table. |
| Schema file | DBMATE_SCHEMA_FILE |
Corresponds to --schema-file / -s. |
| Disable schema dump | DBMATE_NO_DUMP_SCHEMA |
Corresponds to --no-dump-schema. |
| Wait for database | DBMATE_WAIT |
Corresponds to --wait. |
| Wait timeout | DBMATE_WAIT_TIMEOUT |
Corresponds to --wait-timeout. |
| Wait interval | DBMATE_WAIT_INTERVAL |
Corresponds to --wait-interval. |
| Strict migrations | DBMATE_STRICT |
Corresponds to --strict on up / migrate. |
| Verbose SQL output | DBMATE_VERBOSE |
Corresponds to --verbose / -v on up / migrate / rollback. |
--env and --env-file are CLI-only options (they are not themselves read from environment variables).
Loading .env files
By default, dbmate loads environment variables from a .env file in the current working directory (if present). Missing files are ignored; an invalid dotenv file causes dbmate to exit with an error.
To load one or more alternate dotenv files, pass --env-file (repeatable). When any --env-file is given, only the listed files are loaded - the default .env is not included unless you specify it:
dbmate --env-file .env.development up
dbmate --env-file .env --env-file .env.local up
Files are loaded in the order given.
Variable precedence
From highest to lowest priority:
- Command line flags (for example
--url,--driver,--migrations-dir) - Environment variables already set in the calling process
- Values from dotenv files (
.envor files passed with--env-file) - Built-in defaults
Dotenv files n