Tutorial: Deployment of Golang web app using Systemd

Tutorial: Deployment of Golang web app using Systemd

Today, I am going to show you a simple way of deploying a Golang web application.

We are going to use Systemd and a Makefile to deploy the code when we merge to main branch. In a future blog post we will revisit and show you how you can deploy
when you push to main by utilizing Github Pipelines.

Let's get started πŸ₯³

Setting up Systemd

I assume that you already have a linux VPS. If not, then I recommend you create an account in Digital Ocean using this link . If you register using this link you will get $200 in credit and I will get $25 in case you continue using this. Basically, you can try this for free so give it a try .

The instructions will be for an Ubuntu VPS so if you create a new one now please use the Ubuntu image.

Setting up DNS

Configure your domain to point to your server's ip address.

then ssh into the VPS and do:

In your VPS

sudo touch /etc/systemd/system/invoice-hub.service
mkdir -p /home/giorgos/invoice-server
touch /home/giorgos/invoice-server/.env
sudo mkdir -p /.cache/.certs && sudo chown -R giorgos:giorgos /.cache/.certs

☒️ adjust the paths and the USER

Then open with an editor and paste:

[Unit]
Description=Freelance invoice hub service

[Install]
WantedBy=multi-user.target

[Service]
Type=simple
ExecStart=/home/giorgos/invoice-server/invoice-server
WorkingDirectory=/home/giorgos/invoice-server
EnvironmentFile=/home/giorgos/invoice-server/.env
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n

⚠️ modify the paths to match your servers.

❕this is not the "best" systemd config. However we want to deploy fast and this is good enough. We will revisit in the future

The being still in your VPS edit the .env file you created and add:

FIH_DOMAIN=<YOUR-DOMAIN>

Obviously, replace with your domain.

Now let's reload the systemd and enable the service

sudo systemctl daemon-reload
sudo systemctl enable invoice-hub

In your local computer

Now in your local computer build the program:

GOOS=linux GOARCH=amd64 go build -o invoice-server cmd/main.go

This will create a file invoice-server .
If your VPS uses a different OS or architecture please use the correct enviroment variables. See here for a tutorial .

Now let's manually copy the file to the server

scp invoice-server <USERNAME>@<server-ip>:~/invoice-server/invoice-server

The above command just copies the executable you build to the servers path.

If not already done I highly recommend you create an public/private key pair and use that to login to your server .

This tutorial is not about that, so if you don't know how to do it google or ask ChatGPT .

I like to add an entry in my ~/.ssh/config file like:

Host <just-a-name>
HostName <server-ip>
User giorgos
IdentityFile ~/.ssh/id_rsa
Port 22

Highly recommend to do that.

Then you can ssh using ssh just-a-name .

Enough, with that. I assume you managed to copy your file to the server now.

login again to your VPS

and run:

sudo systemctl start invoice-hub

Now check the status:

And if you did everything correct then you can visit your new web app

YOUR-DOMAIN.com

and you should see the

πŸš€πŸš€πŸš€πŸš€πŸš€

Because it's a little bit tedious to manually build, copy the executable and the run stop and start the service let's automate a bit.

We are going to utilize our make file

Let's create a new branch:

git checkout -b deploy-Makefile-auth

and add the following in your Makefile

deploy: ## deploys to the remote server
    GOOS=linux GOARCH=amd64 go build -o invoice-server cmd/main.go
    scp invoice-server contabo-main:~/invoice-server/invoice-server.2
    ssh myserver sudo systemctl stop invoice-hub
    ssh myserver sudo mv invoice-server/invoice-server.2 invoice-server/invoice-server
    ssh myserver sudo systemctl start invoice-hub

Please replace myserver with your server Host (as you configured in your ~/.ssh/config OR use username@server-ip instead

let's do a change and deploy.

Instead of HELLO WORLD lets make our handler to return

THANK YOU

Change your http/router.go as in the image

and then run

make deploy

wait until the deployment finishes and go to you website

You should see the above .

Basic HTTP Auth

We don't want our web app to be accessible to everyone. Let's configure Basic HTTP Auth.

In our case this is fine since the app will be used only by one user and we are using TLS.

Echo has a middleware that does that for us.

Let's do the following:

go get "github.com/labstack/echo/v4/middleware"

and then in our router.go modify the new method to work like:

As you see in the image we need to store our username and password in the environment variables.

For local development add them in the dev.env

for production set them in your server invoice-server/.env file.

USE SOMETHING SECURE

Let's now test it

make dev

and then when you visit:

https://local.freelance-invoice-hub.com

since it works let's now commit and deploy:

git add .
git commit -m "simple deploy script and basic auth"
git push origin deploy-Makefile-auth

And let's deploy

make deploy

As usual you can find all the code in the related github branch

Summary and what's next

Today we learned a simple way to deploy our Golang applications using Systemd.

This is a really basic method and we can improve our deployments a LOT.

However, the scope of this series is to create a WORKING golang application and at the same time learn that our time is precious. We will do only what is required.
When we have an application working we will keep improving.

Additionally, we learned how to use the Basic Auth Middleware that echo providers

In the next blog we will start coding our application. We will define our domain models and the operations on them.

Until then have fun.

Please comment if something is not clear or does not work for you and I will try to help

Also, don't forget to follow me on X

Β