wmarbut
wmarbut

Reputation: 4685

Serving Go Webapps In production

What's the best way to handle serving a Go web app in production in regards to static content, flexibility, and security?

Should I serve Go from behind a fully buffered reverse proxy like nginx? If so, should I let nginx handle static content?

Should I serve static content from the Go app using a ServeMux and FileServer like what is suggested here Serve homepage and static content from root?

Do I need to using sandboxing like NaCL or AppArmor with my app in production?

Upvotes: 3

Views: 315

Answers (1)

Kyle Lemons
Kyle Lemons

Reputation: 4756

Your question outlines your tradeoffs pretty well. I can't tell you for certain which you should pick, though, as that's going to vary widely depending on your application, but here are some points on each.

Security

You bring up two points about security:

  1. Reverse proxying behind nginx
  2. Sandboxing

If you're running a sensitive application (financial data, etc), terminating SSL connections with nginx (or apache) is going to be a big deal for you because they will be using OpenSSL, which has been vetted and reviewed by numerous security experts. The Go crypto library is very good and is authored by someone who's well-respected in the field, but it has not yet been subject to the same scrutiny.

I can't tell you what's best for your application, but I haven't seen a lot of talk about sandboxing home-grown Go apps when using them to serve in production. One exciting new project that is relevant to this is docker.io, which can give you sandboxing at a number of levels even outside of your Go application. In my opinion, as long as you track the latest releases of Go and you avoid doing unsafe things (like importing "unsafe" and using cgo), using NaCl or AppArmor is probably going to be more trouble than it's worth. That said, sandboxing untrusted Go programs is almost certainly required, if you're doing something like the Go Playground.

Static Content

You can really do this however you want. I'd go with whichever is easiest for you. Go applications can easily serve both their own static content alongside their dynamic content, so I would say that it's often a premature optimization to separate it out until your benchmarks and monitoring tell you it can't handle the load.

Flexibility

I think it's hard to argue with the flexibility of keeping everything in a single binary. That makes it incredibly easy to deploy, it reduces the amount of configuration and monitoring you need to do, etc. What is a static file now can be dynamic later; if it turns out you need in-memory caching or shared memcache, you can add it there. It's often hard to know exactly what you're going to need down the road, so maintaining as much flexibility as possible while you're prototyping and in the initial stages of deployment can be a huge benefit.

As a bonus here that also goes back to both of the earlier questions, if your application/website becomes highly successful you might wind up serving behind a CDN (like CloudFlare, which happens to use Go for some key pieces of their infrastructure) that will both handle caching of your static content and termination of SSL connections. This can be an argument for keeping things simple and minimizing the upfront engineering cost because you can use existing solutions later if required.

Upvotes: 6

Related Questions