← Back to Cecep Azhar
Cecep Azhar #golang#docker#container#devops#deployment

Go dan Docker: Containerizing Aplikasi Go

Cecep Saeful Azhar • 16 Oct 2026
Go dan Docker: Containerizing Aplikasi Go
Tutorial containerizing aplikasi Go dengan Docker. Multi-stage build, optimization, dan docker-compose untuk development.

Go dan Docker: Perfect Match

Salah satu keunggulan Go untuk production adalah binary-nya yang standalone dan small. Tidak ada runtime dependency seperti JVM atau Node.js. Ini membuat Docker image-nya sangat kecil bisa under 10MB! Saya pernah buat Go app dengan Docker image hanya 7MB dibandingkan 200MB+ untuk app Node.js sejenis.

Dockerfile Multi-Stage Build

# Stage 1: Build
FROM golang:1.22-alpine AS builder
WORKDIR /app

COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server ./cmd/server

# Stage 2: Production
FROM alpine:3.19
RUN apk --no-cache add ca-certificates tzdata
ENV TZ=Asia/Jakarta
WORKDIR /app
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]

Optimization Tips

# Build flags untuk binary lebih kecil
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -ldflags="-w -s" -o server ./cmd/server

# -w: remove DWARF debugging info
# -s: remove symbol table
# Hasil: binary 30-40% lebih kecil!

Health Check untuk Production

type HealthStatus struct {
    Status    string            `json:"status"`
    Services  map[string]string `json:"services"`
    Timestamp time.Time         `json:"timestamp"`
}

func HealthCheck(db *gorm.DB) func(c *fiber.Ctx) error {
    return func(c *fiber.Ctx) error {
        status := HealthStatus{
            Status:    "healthy",
            Services:  make(map[string]string),
            Timestamp: time.Now(),
        }
        sqlDB, _ := db.DB()
        if err := sqlDB.Ping(); err != nil {
            status.Services["database"] = "unhealthy"
            status.Status = "degraded"
        } else {
            status.Services["database"] = "healthy"
        }
        statusCode := 200
        if status.Status != "healthy" { statusCode = 503 }
        return c.Status(statusCode).JSON(status)
    }
}

Docker Compose untuk Development

version: "3.8"
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - DB_HOST=postgres
      - DB_PORT=5432
      - DB_USER=dev
      - DB_NAME=myapp_dev
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: devpass
      POSTGRES_DB: myapp_dev
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U dev"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  pgdata:

Image Go yang di-containerize dengan benar itu sangat efisien. Ini salah satu alasan kenapa Go mendominasi cloud-native ecosystem. Docker + Go adalah kombinasi yang powerful untuk SaaS deployment.

Security Best Practices untuk Docker

Security di Docker sering dilupakan. Ini beberapa practices yang saya terapkan:

  1. Jangan pakai root user di container:
FROM alpine:3.19
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
  1. Scan image untuk vulnerabilities dengan trivy atau snyk
  2. Minimal permissions hanya mount volumes yang benar-benar diperlukan
  3. Read-only filesystem tambahkan --read-only flag di production

Docker Build Cache Optimization

Build cache yang baik bisa mengurangi build time dari 5 menit menjadi 30 detik. Kuncinya adalah layer ordering taruh layer yang jarang berubah di atas, yang sering berubah di bawah:

# Good ordering for cache
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./     # Changes rarely
RUN go mod download        # Cached if go.mod unchanged
COPY . .                   # Changes often
RUN go build -o server .

# If only source code changed, go mod download is cached!

Optimasi cache ini terutama penting untuk CI/CD pipeline yang menjalankan build berkali-kali setiap hari.

← More articles from Cecep Azhar Central Content Hub Home →