Go Development

Running Go Applications on DomainIndia VPS (systemd, nginx Reverse Proxy, SSL)

By Domain India Team · DomainIndia EngineeringPublished · Updated 6 min read
Knowledge base article
Contents (12 sections)
TL;DR

Go (Golang) produces a single compiled binary — ideal for lean production deployments on a DomainIndia VPS. This guide covers the full stack: building your binary, running it under systemd, fronting it with nginx or Caddy, and adding Let's Encrypt SSL.

Why Go on a VPS (and not shared)

Go apps are long-running compiled processes listening on a port. Shared hosting (cPanel, DirectAdmin) runs PHP per-request via FastCGI — there's no equivalent for Go. A VPS gives you the systemd services, port control, and iptables needed.

Any Go app — REST API, WebSocket server, gRPC service, static-site generator on a schedule — runs the same way on our VPS:

  1. Compile to a binary on your laptop (or on the VPS)
  2. Upload the binary
  3. Run it as a systemd service
  4. Proxy HTTP via nginx/Caddy
  5. Get SSL via Let's Encrypt

Step 1 — Prepare the VPS

Order a DomainIndia VPS (AlmaLinux 9 or Ubuntu 22.04 recommended). SSH in as root:

  1. Create a non-root user for the app:
    bash
    useradd -m -s /bin/bash goapp
    mkdir -p /home/goapp/app
    chown goapp:goapp /home/goapp/app
  2. Install essentials:
    bash
    # AlmaLinux
    sudo dnf install -y nginx firewalld certbot python3-certbot-nginx
    # Ubuntu
    sudo apt install -y nginx ufw certbot python3-certbot-nginx
  3. Install Go (optional — only if you'll compile on the server):
    bash
    wget https://go.dev/dl/go1.22.0.linux-amd64.tar.gz
    sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz
    echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/go.sh
    source /etc/profile.d/go.sh
    go version

Step 2 — Build your binary

On your laptop (recommended) — cross-compile for Linux:

bash
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o myapp ./cmd/server

Upload:

bash
scp myapp goapp@your-vps-ip:/home/goapp/app/

Or build on the VPS:

bash
cd /home/goapp/app
git clone https://github.com/yourcompany/myapp .
go build -o myapp ./cmd/server
Insight

Keep the binary tiny. CGO_ENABLED=0 go build -ldflags="-s -w" strips debug symbols and cuts binary size 30%. Paired with -trimpath, your binary is reproducible and lean.

Step 3 — Run under systemd

Create /etc/systemd/system/myapp.service:

ini
[Unit]
Description=My Go Application
After=network.target

[Service]
Type=simple
User=goapp
Group=goapp
WorkingDirectory=/home/goapp/app
ExecStart=/home/goapp/app/myapp
Restart=on-failure
RestartSec=5

# Environment
Environment="PORT=8080"
Environment="DATABASE_URL=postgres://user:pass@localhost/dbname?sslmode=disable"
EnvironmentFile=-/home/goapp/app/.env

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/home/goapp/app/data

# Logging
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Start and enable:

bash
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp

Check logs:

bash
sudo journalctl -u myapp -f

Step 4 — nginx reverse proxy

Go listens on port 8080 (internal). nginx takes port 80/443 public traffic and forwards it.

/etc/nginx/conf.d/myapp.conf:

nginx
upstream myapp_backend {
    server 127.0.0.1:8080;
}

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

    # Redirect to HTTPS after SSL setup
    # return 301 https://$host$request_uri;

    location / {
        proxy_pass http://myapp_backend;
        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;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 300s;
    }
}

Test and reload:

bash
sudo nginx -t && sudo systemctl reload nginx

Step 5 — Let's Encrypt SSL

bash
sudo certbot --nginx -d api.yourcompany.com

Certbot modifies your nginx config to add:

  • SSL certificate paths
  • HTTP → HTTPS redirect
  • Auto-renewal cron

Verify renewal:

bash
sudo certbot renew --dry-run

Alternative: Caddy (much simpler)

Caddy auto-obtains Let's Encrypt SSL and auto-renews. /etc/caddy/Caddyfile:

code
api.yourcompany.com {
    reverse_proxy 127.0.0.1:8080
}

That's it. Run sudo systemctl reload caddy — SSL appears within 60 seconds.

See our Nginx vs Caddy comparison article for the trade-offs.

Zero-downtime deployments

For a production API, deploying via "stop → replace binary → start" causes a few seconds of downtime. Two better approaches:

Approach 1 — Graceful restart with SIGHUP:

Use a package like github.com/cloudflare/tableflip or github.com/facebookgo/grace — the old process keeps serving existing requests while the new one picks up new connections.

Approach 2 — Blue-green with systemd:

Run two services (myapp-blue.service + myapp-green.service) on different ports. nginx upstream points to the active one. To deploy:

bash
# Stop green, deploy new binary, start green
sudo systemctl stop myapp-green
cp new-binary /home/goapp/app/myapp-green
sudo systemctl start myapp-green

# Wait for green to become healthy
curl -f http://127.0.0.1:8081/health

# Switch nginx to green, reload
sudo sed -i 's/server 127.0.0.1:8080/server 127.0.0.1:8081/' /etc/nginx/conf.d/myapp.conf
sudo nginx -s reload

Database access

PostgreSQL (recommended for Go):

bash
sudo dnf install -y postgresql-server postgresql-contrib
sudo postgresql-setup --initdb
sudo systemctl enable --now postgresql
sudo -u postgres createdb myapp
sudo -u postgres createuser goapp --pwprompt

Connection string in .env:

code
DATABASE_URL=postgres://goapp:password@localhost/myapp?sslmode=disable

MySQL: install mysql-server, use github.com/go-sql-driver/mysql.

SQLite: fine for small apps, zero setup. Use github.com/mattn/go-sqlite3.

Monitoring

Expose a Prometheus /metrics endpoint in your Go app:

go
import "github.com/prometheus/client_golang/prometheus/promhttp"
http.Handle("/metrics", promhttp.Handler())

On the server, install Prometheus + Grafana (or use Grafana Cloud's free tier — 10k metrics, 50 GB logs free).

Common pitfalls

Binary won't run — "exec format error"
cross-compile target mismatch. VPS is amd64, you compiled for arm64 (Apple Silicon default). Set GOARCH=amd64 explicitly.
"listen tcp :8080: bind: address already in use"
previous process didn't shut down. sudo systemctl stop myapp + sudo lsof -i :8080 to find the holder.
Works locally, crashes in production with SIGKILL
OOM killer. Go apps allocate generously on small-RAM VPS. Set GOMEMLIMIT=256MiB to tell the runtime your budget.
SSL fails — "no such file or directory"
Let's Encrypt rate limit hit, or DNS not yet pointing to the VPS IP. Wait 30 min and retry.
nginx returns 502 Bad Gateway
Go app crashed or isn't listening. Check sudo journalctl -u myapp -n 100.

FAQ

Can I run Go on shared hosting?

No. Shared hosting doesn't allow long-running daemons or custom port binding. You need VPS (or our App Platform for simpler deploys).

How much RAM do I need?

Lightweight Go APIs run fine on 1 GB VPS. For ~1000 concurrent requests with DB, 2 GB is safer. Go is memory-efficient by default.

Should I use gin, echo, fiber, or chi?

For REST APIs, chi (standard-library-friendly) and echo (full-featured) are popular. fiber (fasthttp-based) is fastest but deviates from net/http. For serious production, stick with net/http or chi.

How do I update Go without breaking my running app?

Compile the binary with the new Go version, drop it in, systemctl restart myapp. The Go runtime is statically linked — the Go version on disk doesn't matter to an already-compiled binary.

What's the cheapest DomainIndia VPS for Go?

Start with VPS Starter — 1 vCPU, 2 GB RAM, 40 GB SSD. Enough for most API workloads up to 200 req/sec.

Ready to deploy Go? Order a VPS and get root access today. View VPS plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app
Run Go (Golang) Apps on DomainIndia VPS — Complete Deployment Guide