Building and Deploying a Go‑Gin Web Application with Docker: From Installation to Comparison with Koa
This tutorial walks through installing Go, using the Go‑Gin framework, creating a simple cron‑enabled web service, building Docker images with and without multi‑stage builds, pushing them to a registry, deploying on a server, and comparing the final image size with an equivalent Koa implementation.
This article explains how to develop a Go‑Gin web application, containerize it with Docker, and compare the resulting image size with a similar Koa project.
1. Install Go
Download the appropriate Go version (e.g., go1.22.4) from the official website and install it. Beginners are encouraged to spend some time learning Go's concise syntax.
2. Go Toolchain
Go provides a convenient toolchain. Common commands include:
Command
Function
Example go run Run a Go source file
go run main.go go buildCompile packages and dependencies
go build go testRun automated tests
go test go fmtFormat Go code
go fmt ./... go modManage Go modules
go mod tidy go getDownload and install packages
go get <package_path> go installCompile and install a package
go install <package_path> golintStatic code analysis
golint ./...2.1 go mod sub‑commands
Since Go 1.13, go mod is the default dependency manager. Useful sub‑commands:
Sub‑command
Function
Example init Initialize a new module
go mod init example.com/mymodule tidyClean up dependencies
go mod tidy downloadDownload all module requirements
go mod download3. Introduction to go‑gin
go‑gin is a lightweight, fast web framework for Go with features such as middleware support, JSON validation, grouped routing, error handling, and a built‑in rendering engine. Its API feels very similar to Koa for developers familiar with Node.js.
4. Initialize a go‑gin project
cd your_dir
go mod init your_project_name
# Install dependencies
go get -u github.com/gin-gonic/gin
go get -u github.com/robfig/cron5. Write a simple service
package main
import (
"github.com/gin-gonic/gin"
"github.com/robfig/cron"
"net/http"
"time"
"fmt"
)
func main() {
r := gin.Default()
c := cron.New()
// Add a task that runs every minute
c.AddFunc("*/1 * * * *", func() {
fmt.Println("Executing scheduled task:", time.Now())
})
c.Start()
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": "pong"})
})
r.Run() // listen and serve on 0.0.0.0:8080
}The program imports Gin and Cron, creates a cron job that prints a timestamp every minute, and exposes a "/" endpoint returning a JSON response.
6. Add Dockerfile
6.1 Single‑stage build (no multi‑stage)
FROM golang:1.22.2-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main .
EXPOSE 8080
CMD ["./main"]Building this image results in a size of about 596+MB because the build environment remains in the final image.
6.2 Multi‑stage build
# First stage: build the binary
FROM golang:1.22.2-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main .
# Second stage: lightweight runtime
FROM alpine:latest
WORKDIR /root/
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["./main"]The resulting image is only about 18 MB, dramatically smaller than the single‑stage version.
7. Build and push the Docker image
Log in to your registry (example uses Alibaba Cloud), tag the image, and push it:
# Build the image (no‑stage example)
docker build -t cron-app --no-stage .
# Log in to the registry
docker login --username=<your_user_name> <your_registry>
# Tag the image
docker tag [ImageId] <your_registry>/<your_name>/<image_name>:v1
# Push the image
docker push <your_registry>/<your_name>/<image_name>:v18. Deploy the image on a server
# SSH into the server
ssh root@<your_ip>
# Log in to the registry from the server
docker login --username=<your_user_name> <your_registry>
# Pull the image
docker pull <your_image>
# Run the container
docker run -p 8080:8080 <image_id>
# Verify the container is running
docker psThe service runs on port 8080 and executes the scheduled task once per minute.
9. Compare with a Koa implementation
A similar Koa + node‑cron project produces a Docker image of roughly 122 MB, far larger than the Go binary image (~15 MB). While Koa can be further optimized with bundlers like Webpack, Go’s ability to compile to a single static binary gives it a clear size advantage.
10. Conclusion
The article demonstrates a fast end‑to‑end workflow for building, containerizing, and deploying a Go‑Gin application, highlighting the benefits of Go’s compiled binaries and multi‑stage Docker builds compared with a comparable Node.js/Koa solution.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
