Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run Go migrations on heroku on release?

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?

like image 939
mrEvgenX Avatar asked Oct 05 '19 17:10

mrEvgenX


People also ask

Does heroku run migrations automatically?

Heroku makes deploying Ruby web app a breeze, however it doesn't run rake db:migrate automatically each time you push a new commit to it.


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 (
...
like image 183
Tony Avatar answered Sep 30 '22 10:09

Tony