2

I want to use Golang as my server side language, but everything I've read points to nginx as the web server rather than relying on net/http (not that it's bad, but it just seems preferable overall, not the point of this post though).

I've found a few articles on using fastcgi with Golang, but I have no luck in finding anything on reverse proxies and HTTP and whatnot, other than this benchmark which doesn't go into enough detail unfortunately.

Are there any tutorials/guides available on how this operates?

For example there is a big post on Stackoverflow detailing it with Node, but I cannot find a similar one for go.

Community
  • 1
  • 1
mickdoe
  • 91
  • 4

2 Answers2

1

That's not needed at all anymore unless you're using nginx for caching, Golang 1.6+ is more than good enough to server http and https directly.

However if you're insisting, and I will secretly judge you and laugh at you, here's the work flow:

  1. Your go app listens on a local port, say "127.0.0.1:8080"
  2. nginx listens on 0.0.0.0:80 and 0.0.0.0:443 and proxies all requests to 127.0.0.1:8080.
  3. Be judged.

The nginx setup in Node.js + Nginx - What now? is exactly the same setup you would use for Go, or any other standalone server for that matter that isn't cgi/fastcgi.

Community
  • 1
  • 1
OneOfOne
  • 95,033
  • 20
  • 184
  • 185
  • Even with things like load balancing? Go will handle that? – mickdoe Apr 27 '16 at 02:34
  • 1
    @mickdoe no, but there are packages for that, however that is a legitimate reason to use nginx, I won't judge you for it. ;) You will be judged for running a single nginx instance just to serve a single go app, a lot of people do that. – OneOfOne Apr 27 '16 at 02:36
  • Hmm, you're quickly changing my mind. :) So I could theoretically use `net/http` for quite awhile then? – mickdoe Apr 27 '16 at 02:37
  • 1
    yes, I generally use it for most things. Some times it's fronted by something else, but only if you need load balancing or are hosting at Heroku or some place where they always front your webserver with their infrastructure. – David Budworth Apr 27 '16 at 02:39
  • And TLS is quite optimized on amd64 systems now, specially if the CPU has aes-ni instructions, so you don't have to worry about https being slow on pure go (which was a legit concern on older versions of go). – OneOfOne Apr 27 '16 at 03:16
  • Yeah, this answer is silly. Microservices are not a magic bullet. Nginx is useful for more than just caching. Things like basic auth, balancing, virtual hosting/SNI, being able to quickly reload certificates for HTTPS (and Nginx can do this gracefully without even restarting) without restarting your application (which may- and likely does - have a longer start-up time)... Let your web daemon be your web daemon. Let your application be your application. – brent saner Jul 27 '21 at 03:43
1

I use Nginx in production very effectively, using Unix sockets instead of TCP for the FastCGI connection. This code snippet comes from Manners, but you can adapt it for the normal Go api quite easily.

func isUnixNetwork(addr string) bool {
    return strings.HasPrefix(addr, "/") || strings.HasPrefix(addr, ".")
}

func listenToUnix(bind string) (listener net.Listener, err error) {
    _, err = os.Stat(bind)
    if err == nil {
        // socket exists and is "already in use";
        // presume this is from earlier run and therefore delete it
        err = os.Remove(bind)
        if err != nil {
            return
        }
    } else if !os.IsNotExist(err) {
        return
    }
    listener, err = net.Listen("unix", bind)
    return
}

func listen(bind string) (listener net.Listener, err error) {
    if isUnixNetwork(bind) {
        logger.Printf("Listening on unix socket %s\n", bind)
        return listenToUnix(bind)
    } else if strings.Contains(bind, ":") {
        logger.Printf("Listening on tcp socket %s\n", bind)
        return net.Listen("tcp", bind)
    } else {
        return nil, fmt.Errorf("error while parsing bind arg %v", bind)
    }
}

Take a look around about line 252, which is where the switching happens between HTTP over a TCP connection and FastCGI over Unix-domain sockets.

With Unix sockets, you have to adjust your startup scripts to ensure that the sockets are created in an orderly way with the correct ownership and permissions. If you get that right, the rest is easy.


To answer other remarks about why you would want to use Nginx, it always depends on your use-case. I have Nginx-hosted static/PHP websites; it is convenient to use it as a reverse-proxy on the same server in such cases.

Rick-777
  • 9,714
  • 5
  • 34
  • 50