Ответ
Я предпочитаю подход, при котором Dockerfile копирует локальные файлы, а не клонирует репозиторий самостоятельно. Это дает больше контроля над кэшированием слоев.
Стандартный подход (рекомендуемый):
- Клонирую репозиторий локально.
- В Dockerfile использую инструкцию
COPY. - Использую
.dockerignore, чтобы исключить ненужные файлы.
Пример Dockerfile:
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 -o /app/main ./cmd/api
# Финальный минимальный образ
FROM alpine:latest
COPY --from=builder /app/main /usr/local/bin/main
CMD ["main"]
Важные моменты:
.dockerignore— обязателен. Я добавляю туда.git/,*.log, временные файлы IDE, чтобы не раздувать контекст сборки.- Многостадийная сборка — как в примере выше, позволяет не включать в итоговый образ историю Git, исходный код или инструменты компиляции.
- Клонирование внутри Dockerfile (
RUN git clone) я избегаю, так как это усложняет кэширование, увеличивает размер образа и требует наличияgitв промежуточном образе.