PocketBase comes with a very simple database migrations runner accessible via the migrate command.

    migrate create

    The easiest way to create a new migration is to use migrate create during development:

    // Since the "create" command makes sense only during development, // it is expected the user to be in the app working directory // and to be using "go run ..." [root@dev project]$ go run main.go migrate create "your_new_migration"

    The above will create a new directory migrations with the generated migration file inside it:

    // migrations/1655834400_your_new_migration.go package migrations import ( "github.com/pocketbase/dbx" "github.com/pocketbase/pocketbase/daos" m "github.com/pocketbase/pocketbase/migrations" ) func init() { m.Register(func(db dbx.Builder) error { // set a default "pending" status to all articles query := db.NewQuery("UPDATE articles SET status = 'pending' WHERE status = ''") if _, err := query.Execute(); err != nil { return err } // you can also access the Dao helpers dao := daos.New(db) record, _ := dao.FindRecordById("articles", "RECORD_ID") record.Set("status", "active") if err := dao.SaveRecord(record); err != nil { return err } return nil }, func(db dbx.Builder) error { // revert changes... return nil }) }
    Because the migrations are Go functions, besides applying schema changes, they could be used also to adjust existing data to fit the new schema or any other app specific logic that you want to run only once.
    And as a bonus, being .go files also ensures that the migrations will be embedded seamlessly in your final executable.

    To make your application aware of the registered migrations, you simply have to import the above migrations package in one of your main package files:

    package main import _ "yourpackage/migrations" // ...

    When you deploy the final executable on your production server, the new migrations will be auto applied with the start of the application. Optionally, you could apply them explicitly using migrate up:

    [root@dev ~]$ ./yourapp migrate up

    To revert the last applied migration(s), you could run migrate down [number]:

    [root@dev ~]$ ./yourapp migrate down

    migrate collections

    Since v0.4.0 PocketBase comes with a new migrate collections command that will generate a full snapshot of your current Collections configuration without having to type it manually:

    // Since the "collections" command makes sense only during development, // it is expected the user to be in the app working directory // and to be using "go run ..." [root@dev project]$ go run main.go migrate collections

    Similar to the migrate create command, this will generate a new migration file in the migrations directory.

    It is safe to run the command multiple times and generate multiple migration files. The recommended flow usually is:

    1. make Collection(s) changes locally from the Admin UI
    2. run the migrate collections command
    3. build your app, aka. go build
    4. deploy on prod
    5. repeat...

    You can visually review how the migration will be applied by copying the JSON from the generated migration file and paste it in the receiving environment in "Admin UI > Settings > Import collections".

    PocketBase allows making Collection changes from the Admin UI and therefore there are some caveats/limitations related to the automated Collections migration:

    • It works only for new projects (v0.4.0+).
    • It is recommended to enable the "Hide collection create and edit controls" option in the Admin UI on the prod environment.
      This is because manual Collection changes made from the Admin UI in the migration receiving environment (eg. prod) could conflict with the migration file generated from the local environment since the migration relies on the Collection and Field IDs, which will differ on the two environments if created manually.