Назад к вопросам
Middle
82
questionbank

Какие лучшие практики существуют для использования инструкций ADD и COPY в Docker?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Для инструкций ADD и COPY в Docker существует несколько лучших практик, направленных на повышение безопасности, прозрачности и эффективности сборки образов.

Основное различие между ADD и COPY:

  • COPY просто копирует файлы и директории из указанного источника на хосте в указанную точку назначения в контейнере. Источник должен быть локальным файлом или директорией.
  • ADD имеет более широкие возможности: она может копировать локальные файлы и директории, а также извлекать архивы (tar, gzip, bzip2) и получать файлы по URL.

Лучшие практики:

  1. Предпочитайте COPY перед ADD: В большинстве случаев достаточно COPY. Она более прозрачна, так как просто копирует локальные файлы. Использование ADD для извлечения архивов или загрузки по URL может быть менее предсказуемым и увеличивать сложность сборки.

  2. Используйте COPY для локальных файлов: Если вам нужно скопировать файлы из контекста сборки в образ, всегда используйте COPY.

    # Вместо ADD . /app
    COPY . /app 
    
  3. Будьте осторожны с URL в ADD: Использование ADD с URL может привести к нестабильности сборки, если удаленный ресурс недоступен. Также это может быть менее безопасным, так как вы зависите от внешнего источника. Предпочтительно использовать curl или wget в отдельном слое (RUN) для загрузки ресурсов по URL, что дает больше контроля и позволяет выполнять проверку контрольной суммы.

    # Вместо ADD http://example.com/file.tar.gz /tmp/
    RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* \
        && curl -fsSL http://example.com/file.tar.gz -o /tmp/file.tar.gz \
        && tar -xzf /tmp/file.tar.gz -C /app \
        && rm /tmp/file.tar.gz
    
  4. Извлекайте архивы в отдельном слое при использовании ADD: Если вы должны использовать ADD для извлечения архива (менее распространенный сценарий), убедитесь, что вы делаете это в отдельном слое. Однако, как упомянуто ранее, зачастую более явное извлечение с помощью RUN предпочтительнее.

  5. Копируйте только необходимые файлы: Не копируйте весь контекст сборки (COPY . /app), если в нем есть ненужные файлы (исходный код, тестовые данные, скрытые директории и т.п.). Используйте .dockerignore для исключения этих файлов. Это сокращает размер образа и ускоряет сборку за счет уменьшения объема данных, передаваемых Docker-демону.

    Пример .dockerignore:

    .git
    node_modules
    *.log
    tmp/
    
    # Копируем только необходимые файлы после применения .dockerignore
    COPY . /app
    
  6. Используйте абсолютные пути для назначения: Всегда указывайте абсолютный путь назначения в образе (/app, /usr/local/bin и т.д.). Это делает Dockerfile более понятным и предсказуемым, избегая неопределенности относительно текущего рабочего каталога (WORKDIR).

    # Всегда указывайте абсолютный путь назначения
    COPY src /app/src
    
  7. Варьируйте порядок в зависимости от частоты изменений: Размещайте инструкции COPY или ADD для файлов, которые меняются реже (например, файлы зависимостей, такие как package.json, requirements.txt), выше в Dockerfile, чем инструкции для файлов, которые меняются часто (исходный код приложения). Это позволяет Docker эффективно использовать кэш слоев.

    # Файлы зависимостей (меняются реже)
    COPY requirements.txt /app/
    RUN pip install --no-cache-dir -r requirements.txt
    
    # Исходный код приложения (меняется чаще)
    COPY . /app/ 
    

Сводная таблица:

Инструкция Описание Рекомендуемое использование Чего следует избегать
COPY Копирует локальные файлы/директории Копирование локальных файлов и директорий в образ. Использование, если нужна возможность извлекать архивы или загружать по URL.
ADD Копирует локальные файлы/директории, извлекает архивы, скачивает по URL Использование для автоматического извлечения архивов (редко). Использование для копирования локальных файлов (предпочитайте COPY). Использование для загрузки по URL.

Соблюдение этих практик приводит к созданию более надежных, безопасных и эффективных образов Docker.