The first rule of “faster builds” is to have less dependencies. But that’s not always possible.
Add all your dependencies into the project to avoid the download in Runway’s builder. The downside of this approach is that your repository is a bit larger as it contains all the libraries needed to build, but if we disregard this, then this is the best approach.
Steps include:
go mod verify
go mod tidy
go mod vendor
git add vendor
git commit -m 'Chore(deps): updated vendors'
Then, add the following config:
runway app config set \
BP_GO_BUILD_FLAGS=-mod=vendor
[build]
[[build.env]]
name="BP_GO_BUILD_FLAGS"
value="-mod=vendor"
As we alluded in the basic guide, it may make sense to combine your processes into one binary in order to leverage Golang’s build caching effectively.
Instead of building multiple binaries (cmd/server
, cmd/worker
), combine them in one and leverage the power of CLI libraries (such as urfave/cli
or cobra
) to combine features into one binary:
./app server
./app worker
The following is an example with urfave/cli
:
$ tree
├── Procfile
├── go.mod
├── go.sum
└── main.go
package main
import (
"fmt"
"log"
"os"
"context"
"github.com/urfave/cli/v3"
)
// http handler
func hello(w http.ResponseWriter, req *http.Request) {
log.Print("hello from runway's logs")
fmt.Fprintf(w, "hello from Runway!\n")
}
func main() {
cmd := &cli.Command{
Commands: []*cli.Command{
{
Name: "server",
Usage: "my server",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "port",
Value: "5000", // Runway default
Usage: "server port",
Sources: cli.EnvVars("PORT"),
},
},
Action: func(_ context.Context, cmd *cli.Command) error {
http.HandleFunc("/", hello)
log.Printf("listening on %s", cmd.String("port"))
return http.ListenAndServe(":" + cmd.String("port"), nil)
},
},
{
Name: "worker",
Action: func(_ context.Context, cmd *cli.Command) error {
fmt.Println("I am a worker")
return nil
},
},
},
}
if err := cmd.Run(context.Background(), os.Args); err != nil {
log.Fatal(err)
}
}
The Procfile is needed here so Runway knows to run your-app-name server
to start the server.
Check the Procfile guide for details.
Replace your-app-name
with the name of your Runway app.
web: your-app-name server