How to Deploy Go lang Application on VPS Server?
I like to use Go programming language to write applications in server to handle services such as API and background processes. If you want to learn Go, visit the official Go website .
In this tutorial I just created a sample code to handle HTTP request. Just create a file and anme it main.go
, and put this code in it.
package main
import (
"fmt"
"log"
"net/http"
)
func handleFunc(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
func main() {
http.HandleFunc("/api", handleFunc)
log.Println("Server is running:", 3001);
log.Fatal(http.ListenAndServe(":3001", nil))
}
to run this code, use go run main.go
. the output will be Server is running: 3001
.
To see if it works, open your internet browser (Chrome or Firefox) and type http://localhost:3001/api
and you’ll see Hello!
in the page.
In a real world project you’ll have alot of files. In this article I would like to show you how to build your Golang project into one file and deploy it on your Linux VPS.
Step 1: create a deploy file π
I usually create a bash file. This file contains custom commands so we can run it once to save time.
Open your terminal, create deploy.sh
file and change its permission to be executable.
touch deploy.sh
chmod u+x deploy.sh
Now edit deploy.sh
with the following content.
#!/bin/sh
GOOS=linux GOARCH=amd64 go build -o myapp
To build project, navigate to your project folder and run ./deploy.sh
.
It will compile the project and create a new executable file called myapp
. This is the application which we will copy over to VPS server and run it there.
step 2 : setup the Linux VPS π
There are too many hosting providers such as Linode, Oracle, Google Cloud, AWS, Hostgator, Hostinger, .. etc. Choose one of them and create an account and buy a VPS (virtual private server) to deploy your project in.
After creating an account on one of them, you should have root access to your VPS. So, open terminal and login to your VPS via SSH like this.
make sure to use your VPS server IP address instead of 12.13.14.15
in the command above.
step 3 : setup Nginx π
We’ll use nginx as a proxy handler. For example, our Go application is running on port 3001 inside the server, bur in nginx we can setup it to handle http requests on port 80 or 443 (if you have SSL certificate setup).
sudo apt update
sudo apt install nginx
sudo ufw allow 'Nginx HTTP'
step 4 : setup HTTPS using Let’s Encrypt π
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot python-certbot-nginx
create cert file for your domain.
sudo certbot --nginx certonly
Enter your domain, for example valueinbrief.com
. Then enable auto renew.
sudo certbot renew --dry-run
step 5 : Move your application file to server π
Go to your project folder, and copy the project executable file (the application) over to the server via this command.
scp ./myapp [email protected]:/var/www/
replace 1.2.3.4
with your VPS server IP.
note: I chose to copy the app into /var/www/
folder as you can see in the command above. And I recommend you to do the same.
step 6 : create a service to run Go application π
We need to create a sytem service to run our application.
let’s create a new file /etc/systemd/system/myapp.service
with following content.
Remember to change ExecStart=/var/www/myapp
and Environment=GOPATH=/var/www/
to match your application root folder and appcation file name,
in this demo I stored myapp
file in /var/www/
.
[Unit]
Description=Example API Server
Requires=mysql.service
After=network.target
After=mysql.service
[Service]
User=root
Group=www-data
Environment=GOPATH=/var/www/
ExecStart=/var/www/myapp
[Install]
WantedBy=multi-user.target
In this service file I added mysql. if you donβt use MySQL server you can remove its line from the file above.
Now, we’ll start the service (Start and running our Golang App) by run this command.
sudo systemctl start myapp
To stop the service, we use this command.
sudo systemctl stop myapp
step 7: Create Nginx Configure file to handle proxy for our application π
Create a file /etc/nginx/sites-enabled/domain.com
but replace domain.com
with your actual domain.
And add this content inside the file.
server {
listen 80;
server_name domain.com www.domain.com;
return 301 https://$server_name$request_uri;
}
server {
server_name domain.com www.domain.com;
listen 443 ssl;
ssl on;
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
root /var/www/html;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /ws {
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:3001/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Remember to change domain.com
to your actual domain name.
In this tutorial I included websocket config as well you can see it using location /ws
.
To restart NGINX server, use this command.
systemctl restart nginx
We’re done. See you on the next post .