Какими способами можно добавить исходный код или артефакты сборки в Docker-образ или контейнер?

Ответ

Существует несколько основных способов добавления файлов в Docker, каждый из которых подходит для своих задач:

  1. Инструкция COPY в Dockerfile (Рекомендуемый способ) Самый простой и предсказуемый способ скопировать файлы и директории из контекста сборки в образ.

    # Dockerfile
    FROM golang:1.21-alpine AS builder
    WORKDIR /app
    COPY go.mod go.sum ./
    RUN go mod download
    COPY . .
    RUN go build -o /main .
    
    FROM alpine:latest
    # Копируем только скомпилированный бинарник из предыдущей стадии
    COPY --from=builder /main /main
    CMD ["/main"]
  2. Монтирование томов (Volumes) Используется для разработки и для сохранения данных во время работы контейнера. Не добавляет файлы в сам образ.

    • Bind Mounts (для разработки): монтирует директорию с хост-машины в контейнер. Изменения в коде сразу видны внутри контейнера.
      docker run -v $(pwd):/app my-image
    • Named Volumes (для данных): Docker управляет хранилищем. Используется для баз данных, логов и т.д.
      docker run -v my-app-data:/data my-db-image
  3. Инструкция ADD в Dockerfile Похожа на COPY, но с дополнительными возможностями, такими как распаковка tar-архивов и загрузка файлов по URL. Из-за менее предсказуемого поведения рекомендуется использовать COPY, если эти функции не нужны.

  4. Клонирование из Git-репозитория Можно клонировать репозиторий прямо внутри Dockerfile. Не рекомендуется для production, так как это создает зависимость от сети и добавляет в образ лишние данные (например, историю .git).

    RUN apk add --no-cache git && 
        git clone https://github.com/user/repo.git

Ключевая рекомендация для production: всегда использовать multi-stage builds, чтобы финальный образ содержал только скомпилированный бинарник и необходимые для его запуска файлы. Это делает образ меньше, безопаснее и быстрее.