Ответ
Чтобы минимизировать время пересборки тяжелого Docker-образа, я применяю несколько практик:
-
Использую многоступенчатые сборки (multi-stage builds). Это позволяет отделить среду сборки от финального рантайм-образа, копируя только необходимые артефакты.
# Stage 1: Builder FROM golang:1.20-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o /myapp # Stage 2: Final lightweight image FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=builder /myapp . CMD ["./myapp"] -
Оптимизирую порядок инструкций и кэширование слоев. Сначала добавляю редко меняющиеся файлы (зависимости), затем часто меняющийся код.
# Сначала зависимости – слой кэшируется надолго COPY package.json package-lock.json ./ RUN npm ci --only=production # Потом исходный код – этот слой пересобирается при каждом изменении COPY src/ ./src -
Объединяю команды
RUNдля уменьшения количества слоев и очистки кэша пакетного менеджера в одной инструкции.RUN apt-get update && apt-get install -y --no-install-recommends some-package && apt-get clean && rm -rf /var/lib/apt/lists/* -
Тщательно настраиваю
.dockerignore, чтобы исключить из контекста сборки ненужные файлы (.git,node_modules, лог-файлы, временные файлы редактора), что значительно ускоряет передачу контекста Docker-демону. -
Использую BuildKit (
DOCKER_BUILDKIT=1) для более эффективного кэширования и параллельного выполнения этапов сборки.