Files
docs/content/vps/go-systemd.md
2026-07-28 07:20:32 -05:00

4.1 KiB

title, description, section, order
title description section order
Deploy a Go Binary as a Systemd Service Run a Go application as a background service on your Arcline VPS with systemd. vps 5

Deploy a Go Binary as a Systemd Service

Go compiles to a single static binary — no runtime, no dependencies, no package manager. This makes it ideal for running as a systemd service on your Arcline VPS.


Prerequisites

  • A VPS with SSH access
  • A Go binary compiled for Linux amd64 (or arm64 if using an ARM VPS)

Step 1 — Build your Go binary

On your local machine, cross-compile for your target VPS:

# For Linux amd64 (most common)
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o myapp

# For Linux arm64 (e.g., Raspberry Pi)
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o myapp

The CGO_ENABLED=0 flag ensures a fully static binary with no external library dependencies.


Step 2 — Upload the binary

scp myapp yourname@your.vps.ip.address:/tmp/

On the VPS, move it to its final location:

sudo mkdir -p /opt/myapp
sudo mv /tmp/myapp /opt/myapp/
sudo chmod +x /opt/myapp/myapp

Step 3 — Create a systemd service file

sudo nano /etc/systemd/system/myapp.service
[Unit]
Description=My Go Application
After=network.target
Wants=network-online.target

[Service]
Type=simple
User=yourname
Group=yourname
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp
Restart=always
RestartSec=5
EnvironmentFile=-/opt/myapp/.env

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/myapp

[Install]
WantedBy=multi-user.target

Step 4 — Create an environment file

If your app reads configuration from environment variables:

sudo nano /opt/myapp/.env
PORT=8080
DATABASE_PATH=/opt/myapp/data.db
LOG_LEVEL=info

Secure the file:

sudo chmod 600 /opt/myapp/.env
sudo chown yourname:yourname /opt/myapp/.env

Step 5 — Start and enable the service

sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp   # starts on boot

Check the status:

sudo systemctl status myapp

Step 6 — Set up Nginx reverse proxy (if it's a web app)

If your Go app serves HTTP on a port like 8080, put Nginx in front:

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Enable SSL with Certbot:

sudo certbot --nginx -d api.example.com

Managing the service

Command Description
sudo systemctl start myapp Start the service
sudo systemctl stop myapp Stop the service
sudo systemctl restart myapp Restart the service
sudo systemctl status myapp Show status and recent logs
sudo systemctl enable myapp Enable auto-start on boot
sudo systemctl disable myapp Disable auto-start
journalctl -u myapp -f Follow live logs

Updating the binary

# Build new version locally
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o myapp

# Upload
scp myapp yourname@your.vps.ip.address:/tmp/

# On the VPS
sudo systemctl stop myapp
sudo cp /tmp/myapp /opt/myapp/
sudo systemctl start myapp
sudo systemctl status myapp

Logging

Your Go app's stdout and stderr are automatically captured by systemd's journal. View them with:

journalctl -u myapp -f

For persistent log files, your app can write to a file, or you can configure systemd to forward logs to syslog:

sudo mkdir -p /var/log/myapp
sudo chown yourname:yourname /var/log/myapp

Then in your service file, add:

StandardOutput=append:/var/log/myapp/stdout.log
StandardError=append:/var/log/myapp/stderr.log

What's next