Introduction

We can start introducing Go, a general-purpose programming language which has become one of the most popular back-end programming languages. It’s focused on simplicity and it’s a language that is easy and faster to learn than many other languages for programming web applications. For such reasons, deploying using Go will be very good to many back-end developers

Nginx is a big name in the web servers market, mainly because of its weight resource usage and reliability under load. There is a lot of websites that run on Nginx to serve their content. It can also be used as a load balancer or reverse proxy in deployment. It increases security and enhances the application. Together with Go web back-end, Nginx can be a very fast application.

This tutorial is about building a Hello World application in Go and deploy it on Ubuntu 19.04 server with Nginx as reverse proxy.

Prerequisites

To continue with this tutorial, you will need:

  • One Ubuntu 19.04 server with a sudo non-root user and a firewall
  • Go programming language installed
  • Nginx installed
  • A domain name pointed at your server.

We also recommend to secure your connection with a SSL certificate.

Step 1- Building the Go Web Application

The first step will guide you to build a sample Go web application that shows Hello World at your_domain and greets the user at your_domain/greet.

To start, create a directory in your GOPATH directory that will have the secure file. You can give the name of your preference to the folder, but here we’ll use web-go:

$

mkdir $GOPATH/web-go

By entering this, you’ll generate a directory path that goes to ~/go/go-web.

After, run the following code to change the directory to your brand new created folder in GOPATH:

$

cd $GOPATH/go-web

Use nano to create a file named main.go, which will have the source code for your web application:

$

nano main.go

To create the Hello World functionality, add the Go code into the file you have created:

~/go/go-web/main.go

package main

import ( "fmt" "net/http" )

func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") })

http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) {
    name := r.URL.Path[len("/greet/"):]
    fmt.Fprintf(w, "Hello %s\n", name)
})

http.ListenAndServe(":9990", nil)

}

Now let’ understand what the code snipped will do, to begin with the first line.

The first line is the entry point to your application:

~/go/go-web/main.go

package main …

The package main tells the Go compiler to compile the file as an executable program instead of a library.

Then you have the import statements:

~/go/go-web/main.go

import ( "fmt" "net/http" ) …

The snippet will import the needed modules required for this code to work, which include the standard fmt package and the net/http package for your web server.

The next snippet creates your first route in the main function, which is the entry of any Go application:

~/go/go-web/main.go

… func main () { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello World") }) … } …

There will be a parent route /created within func main, which will return the text Hello World when requested.

The second route accepts a URL parameter, in this case a name, to display accompanied by a greeting.

~/go/go-web/main.go

… func main () { … http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) { name := r.URL.Path[len("/greet/"):] fmt.Fprintf(w, "Hello %s\n", name) }) … } …

This uses Go’s URL.Path to save the value after /greet/ and pass it as the name from the URL parameter.

Finally, you instantiate your server:

~/go/go-web/main.go

… func main () { … http.ListenAndServe(":9990", nil) }

This snippet will start the server and expose your application via port 9990 using Go’s intern http server.

When you finish examining the code in main.go, save the file and quit your editor.

After, build the binary executable of your application by running:

$

go build main.go

This command will compile main.go to produce an executable named main.

You have just created a sample Go web application. The next step will generate a systemd unit file to maintain your app running in the background even when there are no accesses in your server.

Step 2 - Creating a Systemd Unit File

In this part, you will generate a systemd unit file to maintain the application working in the background even when a you log out of the server. With this you will have a persistent application, bringing you closer to a production-grade deployment.

The first step is to create a new file in /lib/systemd/system directory called goweb.service with nano:

$

sudo nano /lib/systemd/system/goweb.service

To set the parameters of the service, add the following snippet into the file:

/lib/systemd/system/goweb.service

[Unit] Description=goweb

[Service] Type=simple Restart=always RestartSec=5s ExecStart=/home/user/go/go-web/main

[Install] WantedBy=multi-user.target

The ExecStart=/home/==user==/go/go-web/main variable specifies that the entry for this service is through the main executable located in the /home/==user==/go/go-web directory, where ==user== is the server non-root sudo account username. The line Restart=always will ensure that systemd will always restart the program when it stops. Next, RestartSec=5s will set a five-second wait time between the restart attempts. Lastly, WantedBy=multi-user.target will specify in what state your server enables the server.

Now you can save and exit the file.

After having written the service unit file, start your web service:

$

sudo service goweb start

Then confirm if the service is working with the command:

$

sudo service goweb status

You’ll get the output:

 #######

output

● goweb.service - goweb Loaded: loaded (/lib/systemd/system/goweb.service; disabled; vendor preset: enabled) Active: active (running) since Wed 2019-07-17 23:28:57 UTC; 6s ago Main PID: 1891 (main) Tasks: 4 (limit: 1152) CGroup: /system.slice/goweb.service └─1891 /home/user/go/go-web/main

In the next step we will set up the Nginx reverse proxy.

Step 3- Setting Up a Reverse Proxy with Nginx

To start, change your working directory to sites-available in Nginx directory:

$

cd /etc/nginx/sites-available

Then create a new file and name it the domain on which you want to expose your application. In this example we’ll use your_domain.

$

sudo nano your_domain

Then add the following lines into the file to establish the settings for your_domain:

/etc/nginx/sites-available/your_domain

server { server_name your_domain www.your_domain;

location / {
    proxy_pass http://localhost:9990;
}

}

The next step is to create a symlink of this Nginx configuration in the sites-enabled folder with the following command:

$

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/your_domain

This is a shortcut of a file in other location. The newly created shortcut will reference the original file to adjust to updates when they happen. Nginx requires both directories to have a file.

Next, reload the Nginx configurations by running the reload command:

$

sudo nginx -s reload

Step 4 - Testing the Application

The last step consists in testing the new application with a secure connection to ensure it is working.

Open your web browser and enter: https://==your_domain==

You’re supposed to see a Hello World message. If you saw this after using a https:// in the URL, that means the application is served on a secure connection.

Also try to visit the second route `https://your_domain/greet/your_name, where your_name is the name you wish the app to send greetings.

If the application returns what you entered greeting the name you chose, that means you have your application working.

Conclusion

In this tutorial, you created a web application with Go, using its libraries, set up a reverse proxy with Nginx, and used a SSL certificate on your domain to secure your app.

Read more about: DevelopmentUbuntu