Skip to content

Instantly share code, notes, and snippets.

@chakrit
Last active July 18, 2018 20:34
Show Gist options
  • Save chakrit/8501582 to your computer and use it in GitHub Desktop.
Save chakrit/8501582 to your computer and use it in GitHub Desktop.
On Go binary deploys.

Talked with @anthonybouch and @scomma the other day and told them that I don't do source-deploys with Go programs. It was sort of a gut reaction and also because I havn't quite worked out all the details at that time as I was not at the stage to be thinking about deployments just yet.

Cons

@scomma made note that you could still do git deploys with source and compile on the server and that's right that you can do that but there are some complications:

  • Go requires GOPATH to function. You have to take care of that in your deploy scripts (with the right permissions etc.)
  • All dependencies needs to separately downloaded.
  • All dependencies then needs to be separately compiled before it's linked into the main program. This is sometimes slow (2-3 seconds per library in some case that I observe). The compilation speed go boasts depends a lot on caching--that is--not having to recompile dependencies to recompile your main program.
  • No explicit versioning support for import paths. Whatever on master on github is the version that you must use. Couple this with caching and you can have your own mini dependency hell on production servers if you are not careful.

Pros

Binary deploys eliminate almost all of those issues by resolving them on your local machines first:

  • No needs to setup GOPATH, just one folder to store your binary and related files. Could be as simple as one scp -r or an rsync call.
  • Dependencies are already compiled into the binary. No dependency waits, no extra downloads.
  • No compile delays, already compiled on the much faster dev workstation.
  • No version hell on production. Whoever deployed the code, it's the version on that person's machine.
  • Service restarts are near-instant as it's simply restarting one executable without any extra help (i.e. no build step, no bundle step, no custom server script, just need to start 1 program).
  • You no longer leave your app's source code on production machine. I'd say this might be more secure.

So that's why I think with compiled programs like Go, it's much easier to just deploy the binary. Machines are then easier to setup as well.

Caveats

There are some downsides/caveats however as I see it:

  • You need to setup go with cross-compilation support. This is not hard, as it is an officially supported feature and many people have already experimented with it. There are scripts for automating this. But this is also a thing you must do that's extra from standard installation.

  • You need to compile and deploy the right architecture for your servers. Not a big downside, but a little annoying maybe.

  • No live-editing on production servers. A little inconvenient during the early stages but not a big problem down the road.

@chakrit
Copy link
Author

chakrit commented Jan 21, 2014

I think the dependency thing stems from the fact that the Go people think that everyone should have their master branch super stable at all times. A very idealized worldview. There's no way to even tag the exact commit to use when you use go get, not even version number so I think that makes it a problem on its own.

So in practice, you can actually have everything looks the same but different commits being compiled into the binary (depending on which machine does go get when) which is totally crazy.

Having a single source of truth is definitely a nice idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment