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.
0 COMMENTS