How to run Go migrations on heroku on release?

Viewed 838

I'm writing a webapp in Go which uses Postgres for data storage and deploy in on Heroku. How can I run migrations automatically?

I use Go 1.13, for dependency management I want to use Go Modules.

As a migration tool I tried this https://github.com/golang-migrate/migrate. Locally I just downloaded latest binary from github releases and run CLI utility ./migrate -database $DATABASE_URL -path migrations up.

Heroku Procfile content

release: migrate -database $DATABASE_URL -path migrations up
web: bin/myawesomegoapp

Of course, when I launch git push heroku master I get an error, that "migrate" no such file or directory, release command failed and push rejected.

So, how can I set up project to install migrate command to be able to run it on heroku on every release?

1 Answers

You have to tell Heroku to build it, and it's a bit of a pain. Here's how you make it happen using go modules.

First you have to tell go modules to include it even though it's not referenced in the source. This is discussed here. This is my tools package which lives in tools.go in the root of my project:

// +build tools

package tools

// See this https://github.com/go-modules-by-example/index/blob/master/010_tools/README.md

import (
    _ "github.com/golang-migrate/migrate/v4"
    _ "github.com/golang-migrate/migrate/v4/cmd/migrate"
)

I then vendored my dependencies.

go mod tidy
go mod vendor

Finally, you have to tell Heroku to build the binary for migrate which is not documented very thoroughly. For this you not only need to specify the path where migrate lives, you need to include a "." which tells heroku you also want to look for main packages in the working directory. This is because (I'm guessing) using that directive overrides their default package search behavior. This is what my modules file looks like:

module ...

// +heroku goVersion 1.14
// +heroku install -tags 'postgres' ./vendor/github.com/golang-migrate/migrate/v4/cmd/migrate .

go 1.14

require (
...
Related