Sobes.tech
Middle

Кои са най-добрите практики за използване на инструкциите ADD и COPY в Docker?

sobes.tech AI

Отговор от 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 образи.