Client Area

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

ByDomain India Team·DomainIndia Engineering
5 min read24 Apr 20263 views
# Running Go Applications on DomainIndia VPS (systemd, nginx Reverse Proxy, SSL)
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:
2
Install essentials:
3
Install Go (optional — only if you'll compile on the server):
## 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`: ``` 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](https://domainindia.com/support/kb/nginx-vs-caddy-for-app-gateways-2025-engineer-s-guide) 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`: ``` 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](https://grafana.com/products/cloud/) — 10k metrics, 50 GB logs free). ## Common pitfalls ## FAQ
Q 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).

Q 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.

Q 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.

Q 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.

Q 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 feedback helps us improve our documentation

Still need help? Submit a support ticket

Still need help?

Our support team can assist you directly.

Submit Ticket