Apps Artificial Intelligence CSS DevOps Go JavaScript Laravel Linux MongoDB MySQL PHP Python Rust Svelte Vue

Deploy a Go Web Server with systemd on Linux

2 min read .
Deploy a Go Web Server with systemd on Linux

When developing a small Go web server, it is common to run it manually with go run main.go. The problem is that the process stops when the terminal closes, and it will not automatically return after a server reboot.

A better production setup is to run the application as a systemd service. That gives you automatic startup, monitoring, service management, and optional restart behavior after failures.

1. Create a Simple Go Web Server

Start with a minimal HTTP server:

package main

import (
	"encoding/json"
	"log"
	"net/http"
)

type Response struct {
	Message string `json:"message"`
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(Response{Message: "Success"}); err != nil {
		log.Printf("encode response: %v", err)
	}
}

func main() {
	http.HandleFunc("/", handleRequest)
	log.Fatal(http.ListenAndServe(":8080", nil))
}

The server listens on port 8080 and returns:

{"message":"Success"}

2. Build the Binary

Compile the application:

go build -o myapp main.go

This creates an executable named myapp.

3. Install the Binary

Move it to a standard location:

sudo mv myapp /usr/local/bin/myapp

For real deployments, you may prefer a dedicated application directory such as /opt/myapp if the service needs configuration files or other assets.

4. Create a systemd Unit

Create a service file:

sudo nano /etc/systemd/system/myapp.service

Add:

[Unit]
Description=My Go App
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/myapp
Restart=on-failure
RestartSec=5
User=nobody
Group=nogroup

[Install]
WantedBy=multi-user.target

Important settings:

  • ExecStart points to the compiled Go binary.
  • Restart=on-failure restarts the process after unexpected failures.
  • User and Group run the service without root privileges.

On some Linux distributions, nogroup may not exist. Use an appropriate dedicated service account for your system when deploying a real application.

5. Reload, Start, and Enable the Service

Reload systemd after creating or editing the unit:

sudo systemctl daemon-reload

Start the application:

sudo systemctl start myapp

Enable it at boot:

sudo systemctl enable myapp

You can combine the last two operations with:

sudo systemctl enable --now myapp

6. Check Service Status and Logs

Check whether the service is running:

sudo systemctl status myapp

View logs with journalctl:

sudo journalctl -u myapp -f

7. Test the Server

Run:

curl http://localhost:8080

Expected output:

{"message":"Success"}

Conclusion

Running a Go server under systemd gives you a reliable baseline deployment: the application can start automatically after boot, restart after failures, and be managed consistently through systemctl and journalctl.

For an internet-facing deployment, place a reverse proxy such as Nginx or Caddy in front of the Go service and keep the application itself bound to a private interface whenever appropriate.

Related Posts

chevron-up