Golang App as a Systemd Service
You might have an idea for a go REST api where you don't store configuration within the app but rather get it from an environment variable, how to do this? Well, Kelsey Hightower's envconfig has a library that does that very nicely. Also want to run it as a service, well there's systemd for that. Example app and systemd service files below. Created a simple database called test and created a table within that with userinfo that holds username, firstname, lastname, and team. Then export config info, I use /etc/environment
, this way it is available system wide
Database Schema - Table name=userinfo
id | username | firstname | lastname | team
----+----------+-----------+----------+--------------
Env variables
TEST_DB_USERNAME='tester'
TEST_DB_PASSWORD='secretpassword'
TEST_DB_NAME='databasename'
I exported these variables in /etc/environment
package main
import (
"database/sql"
"fmt"
"log"
"net/http"
"github.com/kelseyhightower/envconfig"
_ "github.com/lib/pq"
)
type DB struct {
Username string
Password string
Name string
}
func main() {
http.HandleFunc("/", sayName) // set router
err := http.ListenAndServe(":8080", nil) // set listen port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func sayName(w http.ResponseWriter, r *http.Request) {
var config DB
err := envconfig.Process("test_db", &config)
checkErr(err)
connectionString := fmt.Sprintf("user=%s password=%s dbname=%s", config.Username, config.Password, config.Name)
db, err := sql.Open("postgres", connectionString)
checkErr(err)
err = db.Ping()
checkErr(err)
rows, err := db.Query("SELECT username,firstname,lastname,team FROM userinfo")
checkErr(err)
for rows.Next() {
var username string
var firstname string
var lastname string
var team string
err = rows.Scan(&username, &firstname, &lastname, &team)
checkErr(err)
fmt.Printf("username | firstname | lastname | team \n")
fmt.Printf("---------+-----------+----------+------\n")
fmt.Printf("%8v | %9v | %8v | %4v\n", username, firstname, lastname, team)
}
}
func checkErr(err error) {
if err != nil {
log.Fatal(err.Error())
}
}
Console output
curl localhost:8080
username | firstname | lastname | team
---------+-----------+----------+------
scholesy | Paul | Scholes | Man Utd
systemd service file
[Unit]
Description=tester service
StartLimitIntervalSec=60
[Service]
Type=simple
EnvironmentFile=-/etc/environment
Restart=on-failure
RestartSec=10
ExecStart=/home/ubuntu/go/src/tester/tester
[Install]
WantedBy=multi-user.target
Enable and start service
sudo mv tester.service /lib/systemd/system/.
sudo chmod 755 /lib/systemd/system/tester.service
sudo systemctl enable tester.service
sudo systemctl start tester