Docker 部署

Docker 是现代应用部署的主流方式,Gin 应用容器化非常简单。

基础 Dockerfile

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 -o main .

FROM alpine:latest

RUN apk --no-cache add ca-certificates tzdata

WORKDIR /root/

COPY --from=builder /app/main .
COPY --from=builder /app/config ./config

ENV TZ=Asia/Shanghai

EXPOSE 8080

CMD ["./main"]

多阶段构建

优化镜像大小:

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

FROM scratch

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/main /main

EXPOSE 8080

ENTRYPOINT ["/main"]

docker-compose

version: '3.8'

services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - GIN_MODE=release
      - DB_HOST=db
      - DB_PORT=3306
      - DB_USER=root
      - DB_PASSWORD=password
      - DB_NAME=myapp
      - REDIS_HOST=redis
      - REDIS_PORT=6379
    depends_on:
      - db
      - redis
    restart: always

  db:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=myapp
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306"

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

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app

volumes:
  db_data:

健康检查

FROM golang:1.21-alpine AS builder
# ... 构建步骤 ...

FROM alpine:latest

RUN apk --no-cache add curl

COPY --from=builder /app/main .

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:8080/health || exit 1

EXPOSE 8080

CMD ["./main"]

环境变量配置

FROM alpine:latest

ENV GIN_MODE=release \
    PORT=8080 \
    LOG_LEVEL=info

COPY main .

EXPOSE ${PORT}

CMD ["./main"]

.dockerignore

.git
.gitignore
.env
.env.*
*.md
Makefile
Dockerfile
docker-compose.yml
.idea
.vscode
*.test
*.out
tmp/
logs/

Kubernetes 部署

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gin-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: gin-app
  template:
    metadata:
      labels:
        app: gin-app
    spec:
      containers:
      - name: gin-app
        image: myapp:latest
        ports:
        - containerPort: 8080
        env:
        - name: GIN_MODE
          value: "release"
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: host
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: gin-app-service
spec:
  selector:
    app: gin-app
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer

构建和运行

# 构建镜像
docker build -t myapp:latest .

# 运行容器
docker run -d -p 8080:8080 --name myapp myapp:latest

# 查看日志
docker logs -f myapp

# 使用 docker-compose
docker-compose up -d
docker-compose logs -f app

小结

Docker 部署 Gin 应用简单高效。使用多阶段构建可以大幅减小镜像体积。docker-compose 适合本地开发和测试,Kubernetes 适合生产环境。记得配置健康检查,让容器编排系统能正确管理应用。