Nginx + FastCGI + Go Setup.
UPDATE : Previous code example no longer work since Golang version 1.5. Updated the code example below to work with the latest version
In most examples of Go that I came across that deal with net/http
package, accessing the Go program is usually done via http://localhost:8080/
This is useful if you want to use Go web server on a port.
However, there are times you need a front web server to handle incoming requests and proxy the requests to multiple Go processes.
In this tutorial, we will learn how to connect a Go process via FastCGI and Nginx web server. This tutorial assumes that you already know how to setup Nginx and FastCGI.
In the Nginx server block, you need to configure FastCGI to listen to certain port. For example :
location ~ /go.* {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9001;
}
NOTE : Make sure to include this FastCGI block in HTTPS part of the nginx.conf file if your web server redirects all traffic to HTTPS
We will try to achieve the following :
Print out a "Hello World!" string via the localhost:8080 way
Change the Go program to output via FastCGI.
Ok, let's get started with the "traditional" way
File : nginx_fastcgi.go
package main
import (
"net/http"
)
func HelloHandler(w http.ResponseWriter, r *http.Request) {
html := "Hello"
html = html + " World"
w.Write([]byte(html))
}
func main() {
http.HandleFunc("/", HelloHandler)
http.ListenAndServe(":8080", nil)
}
Pointing the browser to http://example.com:8080/nginx_fastgci will give us "Hello World!" output.
Now, change the above codes to :
package main
import (
"github.com/gorilla/mux"
"log"
"net"
"net/http"
"net/http/fcgi"
)
type customHandler struct {
cmux http.Handler
}
// must have at least ServeHTTP(), otherwise you will get this error
// *customHandler does not implement http.Handler (missing ServeHTTP method)
func (c *customHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
html := "Hello"
html = html + " World"
w.Write([]byte(html))
}
func main() {
mux := mux.NewRouter()
// bind cmux to mx(route)
fcgiHandler := &customHandler{cmux: mux}
mux.Path("/").Handler(fcgiHandler)
listener, _ := net.Listen("tcp", "127.0.0.1:9001") // bind to port 9001 because of - fastcgi_pass 127.0.0.1:9001; in nginx.conf file
err := fcgi.Serve(listener, fcgiHandler)
if err != nil {
log.Fatal(err)
}
}
NOTE : The above code is adapted from previous tutorial on how to create custom handler with Gorilla framework
Test out by running > go run nginx_fastcgi.go
and point your browser to http://example.com/go
you should see the output as the same, but this time without the :8080
port.
Why go
at the end of the URL ? Err.... because it is configured in the Nginx server block.
location ~ /go.* {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9001;
}
To wrap this up, what we did here is to tell nginx_fastcgi.go to listen to new requests pass down via FastCGI and serve the simple Hello World HTML.
Happy coding!
References:
https://www.socketloop.com/tutorials/golang-example-of-custom-handler-for-gorilla-s-path-usage
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+24.2k Golang : Time slice or date sort and reverse sort example
+33.3k Golang : How to check if slice or array is empty?
+9.7k Golang : Setting variable value with ldflags
+5.5k Golang : Error handling methods
+5.4k Fix fatal error: evacuation not done in time problem
+5.2k Golang : Get S3 or CloudFront object or file information
+4.5k PHP : Extract part of a string starting from the middle
+18.4k Unmarshal/Load CSV record into struct in Go
+5.7k Golang : Extract unicode string from another unicode string example
+7.1k Golang : Calculate how many weeks left to go in a given year
+9.1k Golang : Play .WAV file from command line
+9.8k Golang : Find and replace data in all files recursively