CraftCMS Migrations

By Dan Moore, Director of Engineering / Tue Oct 9, 2018
CraftCMS migrations can help you move configuration and content between different environments, allowing you to make sure that changes you make are propagated correctly.

One of my favorite part of CraftCMS is migrations. I think they're unsung heroes of creating a great, maintainable website. (I'm only familiar with CraftCMS v3, so I'm unsure if this post applies to CraftCMS v2.) Craft migrations allow you to run arbitrary code once and only once in an environment, automatically. More in the Craft documentation.
 
After using Craft migrations for a few months, here's some best practices that we've learned:
  • Use Migration Manager. This lets you migrate entries, categories, and other Craft entities without writing a single line of code. By exporting such configuration into JSON, you can then apply the configuration across environments (other developer machines, staging, production). No more manual deployment instructions specifiying "click here, then check this box..." in the editor UI.
  • The Migration Manager isn't perfect. The exported configuration isn't well documented or understandable--it's hard to debug. If you are removing an entity, you can't use the manager; instead you're going to have to write code. It also doesn't provide a rollback method, so such migrations are one way only.
  • Make sure you know all the command line switches. My favorite one is "--interactive 0" . This stops craft from prompting you to run migrations.
  • If you want the full power of migrations, you will want to get familiar with the CraftCMS api, including the services components (for example, the content service) and how to access them via Craft::$app.
  • Migrations are just PHP. If you find yourself writing a lot of the same code, extract the common code out to a utility class.
  • Unlike Rails migrations, which are typically creating database tables, Craft migrations are primarily used to move content and configuration. We've used them to ingest content for a website migration as well.
  • You don't need to provide a safeDown method if your safeUp method is idempotent (that is, can be run multiple times without side effects). Sometimes it's not worth it to provide a rollback method. You need to assess how likely it is that you'd want to roll back the change.
  • Add running migrations to your CI process so that deployments automatically run any migrations. (You will want to use the "--interactive 0" switch.)
  • The migrations table in your craft database is what makes sure migrations happen only once, so if you have an erroneous migration, you may need to modify that table.

Craft migrations let you easily support multiple environments. Because they are just PHP code, anything else that you want to run once and only once can be placed in a migration, version controlled, and deployed across your CraftCMS environments.