Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang production web application configuration

Tags:

go

web

production

For those of you running Go backends in production:

What is your stack / configuration for running a Go web application?

I haven't seen much on this topic besides people using the standard library net/http package to keep a server running. I read using Nginx to pass requests to a Go server - nginx with Go

This seems a little fragile to me. For instance, the server would not automatically restart if the machine was restarted (without additional configuration scripts).

Is there a more solid production setup?

An aside about my intent - I'm planning out a Go powered REST backend server for my next project and want to make sure Go is going to be viable for launching the project live before I invest too much into it.

like image 622
Chaseph Avatar asked Jul 03 '13 05:07

Chaseph


People also ask

Can I build a web application in GoLang?

Build a web application in Golang 🕸 Go is getting more and more popular as the go-to language to build web applications. Go is getting more and more popular as the go-to language to build web applications. This is in no small part due to its speed and application performance, as well as its portability.

Is GoLang good for web applications?

Go is relatively new in the programming world but it has proved to be a suitable choice for web development by supporting Google, YouTube, Netflix, and Uber. It is fast, easy, supports concurrency, and has a great library that does not require additional frameworks.

Is Go production ready?

Namely, the standard library in Go comes with just about everything needed by a developer to build a production-ready application right out of the box. Standardized, easy -to -use packages exist for HTTP requests, cryptography, and database connections, to name only a few.


2 Answers

Go programs can listen on port 80 and serve HTTP requests directly. Instead, you may want to use a reverse proxy in front of your Go program, so that it listens on port 80 and and connects to your program on port, say, 4000. There are many reason for doing the latter: not having to run your Go program as root, serving other websites/services on the same host, SSL termination, load balancing, logging, etc.

I use HAProxy in front. Any reverse proxy could work. Nginx is also a great option (much more popular than HAProxy and capable of doing more).

HAProxy is very easy to configure if you read its documentation (HTML version). My whole haproxy.cfg file for one of my Go projects follows, in case you need a starting pont.

global
        log     127.0.0.1       local0
        maxconn 10000
        user    haproxy
        group   haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend http
        bind :80
        acl  is_stats  hdr(host)       -i      hastats.myapp.com
        use_backend    stats   if      is_stats
        default_backend        myapp
        capture        request header Host     len     20
        capture        request header Referer  len     50

backend myapp
        server  main    127.0.0.1:4000

backend stats
       mode     http
       stats    enable
       stats    scope   http
       stats    scope   myapp
       stats    realm   Haproxy\ Statistics
       stats    uri     /
       stats    auth    username:password

Nginx is even easier.

Regarding service control, I run my Go program as a system service. I think everybody does that. My server runs Ubuntu, so it uses Upstart. I have put this at /etc/init/myapp.conf for Upstart to control my program:

start on runlevel [2345]
stop on runlevel [!2345]

chdir /home/myapp/myapp
setgid myapp
setuid myapp
exec ./myapp start 1>>_logs/stdout.log 2>>_logs/stderr.log

Another aspect is deployment. One option is to deploy by just sending binary file of the program and necessary assets. This is a pretty great solution IMO. I use the other option: compiling on server. (I’ll switch to deploying with binary files when I set up a so-called “Continuous Integration/Deployment” system.)

I have a small shell script on the server that pulls code for my project from a remote Git repository, builds it with Go, copies the binaries and other assets to ~/myapp/, and restarts the service.

Overall, the whole thing is not very different from any other server setup: you have to have a way to run your code and have it serve HTTP requests. In practice, Go has proved to be very stable for this stuff.

like image 113
Mostafa Avatar answered Sep 28 '22 05:09

Mostafa


nginx for:

  • Reverse HTTP proxy to my Go application
  • Static file handling
  • SSL termination
  • HTTP headers (Cache-Control, et. al)
  • Access logs (and therefore leveraging system log rotation)
  • Rewrites (naked to www, http:// to https://, etc.)

nginx makes this very easy, and although you can serve directly from Go thanks to net/http, there's a lot of "re-inventing the wheel" and stuff like global HTTP headers involves some boilerplate you can probably avoid.

supervisord for managing my Go binary. Ubuntu's Upstart (as mentioned by Mostafa) is also good, but I like supervisord as it's relatively distro-agnostic and is well documented.

Supervisord, for me:

  • Runs my Go binary as needed
  • Brings it up after a crash
  • Holds my environmental variables (session auth keys, etc.) as part of a single config.
  • Runs my DB (to make sure my Go binary isn't running without it)
like image 22
elithrar Avatar answered Sep 28 '22 05:09

elithrar