Docker and Containerization with Go
Introduction
Docker enables consistent deployment across environments. This guide covers containerizing Go applications, optimizing images, and best practices for production containers.
Core Concepts
Docker Basics
- Image: Blueprint for containers
- Container: Running instance of an image
- Dockerfile: Instructions to build an image
- Registry: Repository for images
Why Docker?
- Consistency across environments
- Isolation and security
- Easy scaling and deployment
- Simplified dependency management
Good: Creating Dockerfiles
Basic Dockerfile
# โ
GOOD: Simple Dockerfile
FROM golang:1.21
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o app .
EXPOSE 8080
CMD ["./app"]
Multi-Stage Build
# โ
GOOD: Multi-stage build for smaller images
FROM golang:1.21 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
# Final stage
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/app .
EXPOSE 8080
CMD ["./app"]
Optimized Dockerfile
# โ
GOOD: Optimized for production
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /root/
COPY --from=builder /app/app .
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
CMD ["./app"]
Good: Building and Running
Docker Commands
# โ
GOOD: Build image
docker build -t myapp:1.0 .
# โ
GOOD: Run container
docker run -p 8080:8080 myapp:1.0
# โ
GOOD: Run with environment variables
docker run -p 8080:8080 -e DATABASE_URL=postgres://... myapp:1.0
# โ
GOOD: Run in background
docker run -d -p 8080:8080 myapp:1.0
# โ
GOOD: View logs
docker logs <container-id>
# โ
GOOD: Stop container
docker stop <container-id>
# โ
GOOD: Remove image
docker rmi myapp:1.0
Good: Docker Compose
Docker Compose Setup
# โ
GOOD: Docker Compose configuration
version: '3.8'
services:
app:
build: .
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgres://user:password@db:5432/mydb
- LOG_LEVEL=info
depends_on:
- db
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
restart: unless-stopped
db:
image: postgres:15
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data:
Advanced Patterns
.dockerignore
# โ
GOOD: .dockerignore file
.git
.gitignore
.env
.env.local
node_modules
dist
build
*.log
.DS_Store
.vscode
.idea
Build Arguments
# โ
GOOD: Using build arguments
FROM golang:1.21 AS builder
ARG VERSION=dev
ARG BUILD_DATE
WORKDIR /app
COPY . .
RUN go build -ldflags="-X main.Version=${VERSION} -X main.BuildDate=${BUILD_DATE}" -o app .
FROM alpine:latest
COPY --from=builder /app/app .
CMD ["./app"]
Layer Caching
# โ
GOOD: Optimize layer caching
FROM golang:1.21
WORKDIR /app
# Copy only go.mod and go.sum first
COPY go.mod go.sum ./
RUN go mod download
# Copy source code
COPY . .
# Build
RUN go build -o app .
EXPOSE 8080
CMD ["./app"]
Best Practices
1. Use Specific Base Image Versions
# โ
GOOD: Specific version
FROM golang:1.21-alpine
# โ BAD: Latest tag
FROM golang:latest
2. Minimize Image Size
# โ
GOOD: Multi-stage build
FROM golang:1.21 AS builder
RUN go build -o app .
FROM alpine:latest
COPY --from=builder /app/app .
# โ BAD: Large image
FROM golang:1.21
RUN go build -o app .
3. Use Health Checks
# โ
GOOD: Health check
HEALTHCHECK --interval=30s CMD curl -f http://localhost:8080/health
# โ BAD: No health check
4. Don’t Run as Root
# โ
GOOD: Non-root user
RUN addgroup -g 1000 appuser && adduser -D -u 1000 -G appuser appuser
USER appuser
# โ BAD: Run as root
USER root
Resources
- Docker Documentation: https://docs.docker.com/
- Docker Best Practices: https://docs.docker.com/develop/dev-best-practices/
- Go Docker Guide: https://golang.org/doc/tutorial/docker
Summary
Docker containerization ensures consistent deployment across environments. Use multi-stage builds to minimize image size, implement health checks for reliability, and follow security best practices. Proper containerization makes applications portable, scalable, and easier to manage.
Comments