Running a Go Binary as system service
Go is often used to create cli applications of various forms, these can be developer tooling,automation tools or machine agents. The Go binary can run on any system without having install the Go runtime or compiler. CLI applications in Go can be executed by directly executing the binary as:
./binary
This is only suitable for running for testing purposes and it does also not gurantee that it will be running always. There are various approaches to make this run continously and the approach we are going to see is how to run it as a system service on Linux platforms.
Let’s take a very simple program of counting the occurrences of a substring since our main aim is just to have an undertsanding of how to run this as a system service:
package main
import (
"fmt"
"log"
"os"
"strings"
)
var (
WarningLogger *log.Logger
InfoLogger *log.Logger
ErrorLogger *log.Logger
)
func init() {
file, err := os.OpenFile("syslog.log", os.O_APPEND|os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("Error opening log file %v", err)
}
InfoLogger = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
WarningLogger = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
ErrorLogger = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
}
func main() {
var str string = "Hello, there how is it going?"
var manyD = "ddddddddddd"
InfoLogger.Printf("Number of H’s in %s is: ", str)
InfoLogger.Printf("%d\n", strings.Count(str, "H"))
InfoLogger.Printf("Number of double d’s in %s is: ", manyD)
InfoLogger.Printf("%d\n", strings.Count(manyD, "dd"))
}
We are also using the logger system provided by to log the output to a log file.
The steps:
-
First compile the program and generate the binary as:
go build main.go
-
You can create a directory in any location,for this purpose I have created a directory substring and put in the binary file there.
-
Create a main.service file in the following location /lib/systemd/system/ with the following contents:
``` [Unit] Description=Substring Service ConditionPathExists=/opt/substring After=network.target [Service] Type=simple User=root Group=root LimitNOFILE=1024 Restart=on-failure RestartSec=10 WorkingDirectory=/opt/substring/ ExecStart=/opt/substring/main PermissionsStartOnly=true SyslogIdentifier=root [Install] WantedBy=multi-user.target ```
-
Change the permission of the service file as
sudo chmod 755 /lib/systemd/system/main.service
-
Now in the final steps, enable the service and start it:
sudo systemctl daemon-reload sudo systemctl enable main systemctl start main journalctl -u main journalctl -f -u main
That’s it and your Go binary will start running as a system service.