Dockerfile подробное объяснение серии Docker Context|Copy|Add (4)

задняя часть Docker
Dockerfile подробное объяснение серии Docker Context|Copy|Add (4)

Эта статья участвовала в третьем этапе курса «Высокоэффективное обновление» тренировочного лагеря для создателей наггетсов. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.

1 Контекст сборки зеркала (Context)

Если вы обратите внимание, вы увидитеdocker buildКоманда имеет последний...представляет текущий каталог, иDockerfileОн находится в текущем каталоге, поэтому многие новички думают, что этот путь указанDockerfileПуть, по которому он находится, на самом деле неточен. Если он соответствует приведенному выше формату команды, вы можете обнаружить, что он указан вконтекстный путь. Так что же такое контекст?

понять сначалаdocker buildПринцип работы. Docker делится на механизм Docker (то есть демон на стороне сервера) и инструменты на стороне клиента во время выполнения. Движок Docker предоставляет набор REST API, называемыхDocker Remote API, в то время как вdockerКлиентские инструменты, такие как команды, взаимодействуют с механизмом Docker через этот набор API для выполнения различных функций. Поэтому, хотя на первый взгляд кажется, что мы выполняем различныеdockerфункцию, но на самом деле все делается на стороне сервера (движок Docker) с помощью формы удаленного вызова. Кроме того, благодаря такому дизайну C/S нам легко управлять механизмом Docker удаленного сервера.

Когда мы делаем сборку образа, не все настройки проходятRUNПосле выполнения команды часто бывает необходимо скопировать некоторые локальные файлы на зеркало, например,COPYинструкция,ADDинструкции и т.д. а такжеdocker buildКоманда сборки образа на самом деле собирается не локально, а на стороне сервера, то есть в движке Docker. Итак, в этой клиент-серверной архитектуре, как сервер может получить локальные файлы?

Это вводит понятие контекста. При построении пользователь указывает путь для построения контекста изображения,docker buildПосле того, как команда узнает этот путь, она упакует все содержимое по этому пути и загрузит его в механизм Docker. Таким образом, после того как механизм Docker получит этот контекстный пакет, расширение получит все файлы, необходимые для сборки образа.

если вDockerfileНапишите это:

COPY ./package.json /app/

Это не предназначено для повторения выполненияdocker buildв каталоге, где находится командаpackage.json, ни копироватьDockerfileв каталогеpackage.json, вместо копированияконтекств каталогеpackage.json.

следовательно,COPYПути к исходным файлам в таких директивахотносительный путь. Вот почему новички часто спрашиваютCOPY ../package.json /appилиCOPY /opt/xxxx /appПричина, по которой это не работает, заключается в том, что эти пути уже вне контекста, механизм Docker не может получить файлы в этих местах. Если эти файлы действительно нужны, их следует скопировать в каталог контекста.

Теперь вы можете понять команду прямо сейчасdocker build -t nginx:v3 .этот в., который на самом деле является каталогом в указанном контексте,docker buildКоманда упакует содержимое этого каталога в механизм Docker, чтобы помочь создать образ.

Если вы наблюдаетеdocker buildВывод, мы фактически видели этот процесс отправки контекста:

$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
...

Понимание контекста сборки важно для сборки образа, чтобы избежать незаслуженных ошибок. Например, некоторые новички открывают для себяCOPY /opt/xxxx /appВедь не работает, так проще говоряDockerfileПоместил его в корневой каталог жесткого диска для сборки и обнаружил, чтоdocker buildПосле выполнения отправка чего-либо в десятки гигабайт происходит чрезвычайно медленно и подвержена сбоям сборки. Это потому, что эта практика делаетdocker buildУпакуйте весь жесткий диск, что явно является неправильным использованием.

Как правило, это должно бытьDockerfileПомещается в пустой каталог или в корневой каталог проекта. Если в этом каталоге нет нужного файла, необходимо сделать копию нужного файла. Если в каталоге есть вещи, которые вы действительно не хотите передавать в движок Docker при сборке, вы можете использовать.gitignoreтот же синтаксис для записи.dockerignore, который используется для отбраковки вещей, которые не нужно передавать в качестве контекста движку Docker.

Так почему кто-то может подумать, что.указаноDockerfileГде находится каталог? Это связано с тем, что по умолчанию, если не указано дополнительноDockerfileЕсли это так, он будет назван в контекстном каталоге.Dockerfileфайл как Dockerfile.

Это просто поведение по умолчанию, на самом деле,Dockerfileимя файла не должно бытьDockerfile, и не обязательно находиться в каталоге контекста, например, можно использовать-f ../Dockerfile.phpпараметр указывает файл какDockerfile.

Конечно, обычно все привыкли использовать имя файла по умолчанию.Dockerfile, и поместит его в каталог контекста сборки образа.

2 КОПИРОВАТЬ Копировать файлы

Формат

  • COPY [--chown=<user>:<group>] <源路径>... <目标路径>
  • COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]

а такжеRUNКак и инструкции, есть два формата: один похож на командную строку, а другой похож на вызов функции.

COPYДирективы будут взяты из каталога контекста сборки<源路径>скопируйте файлы/каталоги на новый слой внутри зеркала<目标路径>Место нахождения. Например:

COPY package.json /usr/src/app/

<源路径>Подстановочных знаков может быть несколько или даже подстановочные, и правила подстановочных знаков должны соответствовать правилам Go.filepath.Matchтакие правила как:

COPY hom* /mydir/
COPY hom?.txt /mydir/

<目标路径>Это может быть абсолютный путь внутри контейнера или относительный путь относительно рабочего каталога (рабочий каталог можно использовать сWORKDIRкоманду указать). Целевой путь не нужно создавать заранее.Если каталог не существует, он создаст отсутствующий каталог перед копированием файла.

Кроме того, следует отметить, что использованиеCOPYДирективы, различные метаданные исходного файла сохраняются. Такие как права на чтение, запись, выполнение, время изменения файла и т. д. Эта функция полезна для настройки изображения. Особенно, когда файлы, связанные со сборкой, управляются с помощью Git.

При использовании этой команды вы также можете добавить--chown=<user>:<group>возможность изменить пользователя и группу, к которой принадлежит файл.

COPY --chown=55:mygroup files* /mydir/
COPY --chown=bin files* /mydir/
COPY --chown=1 files* /mydir/
COPY --chown=10:11 files* /mydir/

3 Добавьте больше расширенных файлов копирования

ADDинструкция иCOPYФормат и характер в основном одинаковы. Но когдаCOPYНа основе добавления некоторых функций.

  • может бытьURL

    В этом случае механизм Docker попытается загрузить связанный файл в<目标路径>идти. Права доступа к загруженному файлу автоматически устанавливаются на600, если это не желаемое разрешение, то нужно добавить дополнительный слойRUNНастройте разрешения.Кроме того, если загруженный пакет представляет собой сжатый пакет, его необходимо распаковать, а также требуется дополнительный слой.RUNкоманда на распаковку. Так что лучше сразу использоватьRUNкоманду, затем используйтеwgetилиcurlИнструментам лучше загружать, управлять разрешениями, распаковывать, а затем очищать ненужные файлы. Поэтому эта функция непрактична и не рекомендуется.

  • может бытьtar 压缩文件

    Формат сжатияgzip, bzip2так же какxzна случай, если,ADDКоманда автоматически распаковывает сжатый файл в<目标路径>идти.

    В некоторых случаях эта функция автоматической декомпрессии очень полезна, например, официальные зеркала.ubuntuсередина:

    FROM scratch
    ADD ubuntu-xenial-core-cloudimg-amd64-root.tar.gz /
    ...
    

    Но в некоторых случаях, если мы действительно хотим скопировать в него сжатый файл, не распаковывая его, то мы не можем его использоватьADDзаказ.

    в официальном докереДокументация по лучшим практикам Dockerfileтребования, используйте как можно большеCOPY,потому чтоCOPYСемантика очень понятна, просто скопируйте файл иADDОн содержит более сложные функции, поведение которых не обязательно понятно. лучшее использованиеADD, это упомянутый случай, когда требуется автоматическая декомпрессия.

    Также обратите внимание, чтоADDДирективы делают недействительным кеш сборки образа, что потенциально замедляет сборку образа.

    Таким образом, вCOPYа такжеADDПри выборе в команде можно следовать этому принципу, все копирование файлов используетCOPYДиректива, используемая только при необходимости автоматической декомпрессииADD.

    При использовании этой команды вы также можете добавить--chown=<user>:<group>возможность изменить пользователя и группу, к которой принадлежит файл.

    ADD --chown=55:mygroup files* /mydir/
    ADD --chown=bin files* /mydir/
    ADD --chown=1 files* /mydir/
    ADD --chown=10:11 files* /mydir/