Расскажи про опыт контейнеризации приложений в Docker

«Расскажи про опыт контейнеризации приложений в Docker» — вопрос из категории Docker, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Я занимался контейнеризацией микросервисных приложений на Go и Python, а также монолитных legacy-систем. Основная цель — обеспечить воспроизводимость окружения, упростить деплой и подготовить инфраструктуру для оркестрации.

Пример Dockerfile для Go-сервиса с многоступенчатой сборкой:

# Этап сборки
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 /app/service ./cmd/main

# Финальный образ
FROM alpine:latest
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /root/
COPY --from=builder /app/service .
COPY --from=builder /app/configs ./configs
EXPOSE 8080
CMD ["./service"]

Ключевые практики, которые я применял:

  • Использование .dockerignore для исключения ненужных файлов (.git, node_modules, логов), что ускоряет сборку и уменьшает размер образа.
  • Минимизация слоев и размера образа: выбор базовых образов на Alpine, объединение RUN-команд, очистка кэша пакетных менеджеров.
  • Безопасность: запуск контейнера от непривилегированного пользователя (инструкция USER), регулярное обновление базовых образов для устранения уязвимостей.
  • Логирование: настройка вывода логов в stdout/stderr для корректной работы с Docker-драйверами и сборщиками логов (Fluentd, Loki).
  • Оркестрация: подготовка образов с учетом требований Kubernetes (readiness/liveness probes, корректное завершение по сигналам).

Для управления зависимостями между сервисами в разработке использовал docker-compose, что позволяло локально поднимать весь стек (приложение, БД, кэш, очередь).