Published on

Working with Static Assets in Go

Authors

In Go when you build your code it compiles to a binary. This is great as it is super lean and can be run straight from the binary without having to setup any other dependencies. One tricky issue is that your static assets, like DB migration scripts, will not be accessible from inside the binary.

Luckily this is a solved problem, enter Packr. Say for example you have the following project structure

<projectRoot>
|_ api
  |_<various go files>
|_db
  |_ migrate.go
  |_migrations
    |_ 1_some_migration.sql
    |_ 2_some_other_migration.sql

Inside migrate.go you have some code that refers to the SQL files inside of the migrations folder. Ins the migration.go file use Packr to make what its calls a box of the migrations folder as follows:

package db
import (
	"github.com/gobuffalo/packr"
)
...

box := packr.NewBox("./migrations")
...

This box will contain the compiled version of your static files which you can refer to using the Packr box api. For example you can the text contents of a file in this box using:

sqlScript := box.String("1_some_migration.sql")

Or if you are using this specifically to run migrations the sql-migrate tool already has built in support for Packr. I found it very useful to log out box.List() to make sure that the box is being created correctly.

While you are deving Packr looks on your local file system for box files i.e. when you run your code using go run main.go. But when you build the binary of your project you need to install the Packr command line tool to properly compile the Go binary together with the static files you defined in boxes. The docs were not clear on how to install the binary as a go get -u github.com/gobuffalo/packr only downloads the raw Packr source files. After Googling a bit I came across how to install buffalo which is made by the same people who make Packr. It turns out you need to add the name of the package again: go get -u github.com/gobuffalo/packr/packr (note the additional packr on the end) which is similar to how they install the buffalo binary. Using packr you can now build your Go project with your static files as follows: packr build. The packr cli is basically a drop in replacement for the go cli and takes the same flags.