Зачем Docker для Go
Docker позволяет упаковать Go-приложение со всеми зависимостями в контейнер. Преимущества:
Базовый Dockerfile
▸Простой Dockerfile
1FROM golang:1.2123WORKDIR /app45# Копирование go.mod и go.sum6COPY go.mod go.sum ./7RUN go mod download89# Копирование исходного кода10COPY . .1112# Сборка13RUN go build -o server .1415# Запуск16CMD ["./server"]
Multi-Stage Builds
▸Оптимизированный Dockerfile
1# Этап сборки2FROM golang:1.21-alpine AS builder34WORKDIR /app56COPY go.mod go.sum ./7RUN go mod download89COPY . .1011RUN CGO_ENABLED=0 GOOS=linux go build -o server .1213# Этап запуска14FROM alpine:latest1516RUN apk --no-cache add ca-certificates1718WORKDIR /root/1920COPY --from=builder /app/server .2122CMD ["./server"]
▸Преимущества multi-stage
Оптимизация сборки
▸Слои Docker
1FROM golang:1.21-alpine AS builder23WORKDIR /app45# Слой зависимостей (кэшируется)6COPY go.mod go.sum ./7RUN go mod download89# Слой исходного кода (изменяется чаще)10COPY . .1112RUN go build -o server .
▸Использование .dockerignore
1.git2*.md3.env4.env.local5node_modules6vendor
Кроссплатформенная сборка
▸Сборка для разных ОС
1FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builder23ARG TARGETOS4ARG TARGETARCH56WORKDIR /app7COPY . .89RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o server .
▸Сборка
1# Для Linux amd642docker build --platform linux/amd64 -t myapp:amd64 .34# Multi-platform образ5docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
Healthchecks
▸Dockerfile с healthcheck
1FROM golang:1.21-alpine AS builder2# ... сборка ...34FROM alpine:latest5# ...67EXPOSE 808089HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \10 CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 11112CMD ["./server"]
Docker Compose
▸docker-compose.yml
1version: '3.8'23services:4 app:5 build: .6 ports:7 - "8080:8080"8 environment:9 - DB_HOST=postgres10 - DB_PORT=543211 - DB_NAME=mydb12 depends_on:13 - postgres1415 postgres:16 image: postgres:15-alpine17 environment:18 - POSTGRES_DB=mydb19 - POSTGRES_USER=postgres20 - POSTGRES_PASSWORD=secret21 volumes:22 - postgres_data:/var/lib/postgresql/data23 ports:24 - "5432:5432"2526volumes:27 postgres_data:
▸Запуск
1# Сборка и запуск2docker-compose up --build34# В фоновом режиме5docker-compose up -d67# Остановка8docker-compose down
Оптимизация образов
▸Использование alpine
1FROM golang:1.21-alpine2# vs3FROM golang:1.21 # ~800MB vs ~300MB
▸Минимальные зависимости
1FROM scratch23COPY --from=builder /app/server /server45CMD ["/server"]
▸Удаление ненужных файлов
1RUN apt-get update && apt-get install -y --no-install-recommends \2 ca-certificates \3 && rm -rf /var/lib/apt/lists/*
Безопасность
▸Запуск от непривилегированного пользователя
1FROM alpine:latest23RUN adduser -D -u 1001 appuser4USER appuser56COPY --from=builder --chown=appuser:appuser /app/server .78CMD ["./server"]
▸Сканирование уязвимостей
1# Trivy2trivy image myapp:latest34# Docker Scout5docker scout cves myapp:latest
CI/CD с Docker
▸GitHub Actions
1name: Build and Push23on:4 push:5 branches: [main]67jobs:8 build:9 runs-on: ubuntu-latest10 steps:11 - uses: actions/checkout@v41213 - name: Set up Docker Buildx14 uses: docker/setup-buildx-action@v31516 - name: Login to Docker Hub17 uses: docker/login-action@v318 with:19 username: ${{ secrets.DOCKERHUB_USERNAME }}20 password: ${{ secrets.DOCKERHUB_TOKEN }}2122 - name: Build and push23 uses: docker/build-push-action@v524 with:25 push: true26 tags: user/myapp:latest
Заключение
Docker и Go — отличное сочетание для создания лёгких и эффективных контейнеров. Multi-stage builds позволяют создавать минимальные production-образы. На собеседовании спрашивают про оптимизацию Dockerfile, multi-stage builds и безопасность контейнеров.