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
- Set up automated backups with restic
- Install fail2ban for SSH brute-force protection