Deploying a Go Application on VPS: Advanced Guide

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: From Development to Production Server on Go

You have written a high-performance web application in Go (Golang). Compilation into a single binary, static typing, built-in networking — all of this gives it an edge over Node.js or Python. But "it works on my machine" is not an argument for production. Advanced deployment of a Go application on a VPS is not just copying files via SSH. It involves setting up a CI/CD pipeline, containerization, reverse proxy, automatic certificate renewal, monitoring, and graceful shutdown.

In this article, we will break down a complete production-ready scenario for a Golang application on Ubuntu 22.04 LTS. You will learn how to set up a Docker build, organize zero-downtime deployment via GitHub Actions, integrate Nginx with SSL, and configure monitoring with Prometheus metrics.



1. VPS Preparation and Environment Setup

Assume you have a VPS (DigitalOcean, Hetzner, Timeweb) with Ubuntu 22.04. First, update the system and install a basic set of tools:

ssh root@your_server_ipapt update && apt upgrade -yapt install -y git curl htop net-tools ufw

Create a user deploy with sudo privileges (no password, SSH key only):

adduser deployusermod -aG sudo deploymkdir /home/deploy/.sshcp ~/.ssh/authorized_keys /home/deploy/.ssh/chown -R deploy:deploy /home/deploy/.sshchmod 700 /home/deploy/.ssh && chmod 600 /home/deploy/.ssh/authorized_keys

Configure the UFW firewall:

ufw allow OpenSSHufw allow 80/tcpufw allow 443/tcpufw enable

Important: Disable root login in /etc/ssh/sshd_config (PermitRootLogin no) and restart SSH (systemctl restart sshd).



1.1 Installing Docker and Docker Compose

For a Go application, containerization is the de facto standard. Install Docker using the official instructions:

curl -fsSL https://get.docker.com -o get-docker.shsh get-docker.shusermod -aG docker deploy

Check the version: docker --version. Next, install Docker Compose v2 (plugin):

apt install -y docker-compose-plugin


2. CI/CD Pipeline with GitHub Actions and Docker

Advanced deployment implies automation. We will use GitHub Actions to build the image and send it to the server via SSH, followed by launching a new container.

Project structure in Go:

myapp/├── main.go├── go.mod├── Dockerfile├── docker-compose.yml└── .github/workflows/deploy.yml

Dockerfile (Multi-stage build):

FROM golang:1.22-alpine AS builderWORKDIR /appCOPY go.mod go.sum ./RUN go mod downloadCOPY . .RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/myapp .

FROM alpine:latestRUN apk --no-cache add ca-certificates tzdataWORKDIR /root/COPY --from=builder /app/myapp .EXPOSE 8080CMD ["./myapp"]

docker-compose.yml (for production):

version: '3.8'services:  app:    image: ghcr.io/your_username/myapp:latest    restart: always    ports:      - "127.0.0.1:8080:8080"    environment:      - DB_URL=postgres://user:pass@db:5432/mydb    depends_on:      - db  db:    image: postgres:16-alpine    restart: always    environment:      POSTGRES_USER: user      POSTGRES_PASSWORD: pass    volumes:      - pg_data:/var/lib/postgresql/datavolumes:  pg_data:

GitHub Actions workflow (.github/workflows/deploy.yml):

name: Deploy Go Appon:  push:    branches: [ main ]jobs:  build-and-deploy:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v4      - name: Login to GitHub Container Registry        uses: docker/login-action@v3        with:          registry: ghcr.io                

Blogs

Book Recommendations