Single-binary Web Apps in Go and Vue — Part 4
By: Adam Presley
Tags: Software Development, JavaScript, Development, Vuejs, Golang

Photo by David Pisnoy on Unsplash

This is part 4 in a four part series where we will demonstrate building a web application using Go and Vue, and finally bundle it all together in a single binary for super-easy deployment/distribution. Part 1 can be found here, part 2 here, and part 3 here.

In part 1 we built the Go and Vue apps. In part 2 we changed the Go app to automatically start the Vue app by running Node when the version of the application is “development”. In part 3 we bundled it all up into a single compiled binary. In this article, to make our lives easy, we are going to use the tool make to build everything.

If you recall we had to run these commands to make a final bundled build.

$ cd app

$ npm run build

$ cd ..

$ go generate

$ go build -tags=prod -ldflags="-X 'main.Version=1.0.0'"

That’s a lot of steps. Let us simplify. I’ll start by showing the whole Makefile, and then we’ll break it down.

Line 1 is simple. It states that when we run make the default action is run, meaning it will execute the script at line 17.

Line 4 is a variable that identifies the path to UPX. UPX is a nifty tool that compresses executables. Why do I want this? When we bundle in our static JavaScript assets (our Vue app) it makes our final executable fairly large. UPX will make the binary as small as possible.

Lines 6–10 define some variables we are going to use further down.

The variable VERSION is where you can set the version of your application. This is applied to the variable Version in main.go

is where you can set the version of your application. This is applied to the variable in BUILDFLAGS are flags that will be passed to go build. The flag “-s” tells Go to omit the symbol table from the binary, and the flag “-w” says to omit debug information. The “-X” flag is what is setting the version variable in the binary

are flags that will be passed to go build. The flag “-s” tells Go to omit the symbol table from the binary, and the flag “-w” says to omit debug information. The “-X” flag is what is setting the version variable in the binary PROJECTNAME is a variable that is the name of the final executable

is a variable that is the name of the final executable GCVARS contains the environment variables specifying to omit cgo and to use AMD64 architecture

contains the environment variables specifying to omit cgo and to use AMD64 architecture GC is the final Go compile command. This is the string that will run the actual build

Lines 12–15 is a bit of script that ensures that UPX is installed. If it isn’t installed the Make process will stop with an error.

Lines 17 and 18 define the goal named run. This just runs the Go app with the tag “dev”. This will also start the Node server for the Vue app because in main.go the variable Version is “development”.

The final bits define goals to build for various platforms. Notice how each depends on the goal generate-compiled-assets, which in turn depends on build-vue-app. This means that if you run make build-linux it will first build The Vue app, then run “go generate”, then finally run the Go build.