Dockerfile
Dockerfile
скрипт, состоящий из набора команд и параметров,Dockerfile
который включает в себя создание всегоimage
полная команда. Докер черезdocker build
воплощать в жизньDockerfile
Серия команд в автоматической сборкеimage
.
Dockerfile
Синтаксис очень прост, и на этой странице описаны команды, которые вы можете использовать в своем Dockerfile. Прочитав эту страницу, вы можете обратиться кЛучшие практики Dockerfile.
Usage
docker build
команда отDockerfile
иcontext
Создайте образ.context
даPATH
илиURL
файл в.PATH
локальный каталог файлов.URL
— это расположение репозитория Git.
context
Обрабатывается рекурсивно. следовательно,PATH
включая любые подкаталоги,URL
Включает репозиторий и подмодули. Использовать текущий каталог какcontext
Простая команда сборки:
$ docker build .
Sending build context to Docker daemon 6.51 MB
...
Сборки запускаются демоном Docker, а не CLI. Первое, что делает процесс сборки, это отправляет весь контекст (рекурсивно) демону. В большинстве случаев лучше всегоDockerfile
и необходимые файлы в пустой каталог, а затем в этот каталог для сборки.
警告
: не использовать корневой каталог/
как PATH, потому что это заставляет сборку передавать все содержимое жесткого диска демону Docker.
Добавлять файлы при сборке, пройтиDockerfile
Относится к файлу, указанному в директиве, например.COPY
инструкция. Для повышения производительности сборки используйте.dockerignore
файл добавлен вcontext
каталог, чтобы исключить файлы и каталоги. о том, как создать.dockerignoreинформацию о файле см. в документации на этой странице.
В целом,Dockerfile
родыcontext
в корне. но использовать-f
Флаги для указания расположения Dockerfile.
$ docker build -f /path/to/a/Dockerfile .
Если сборка прошла успешно, вы можете указать репозиторий и тег, куда вы хотите сохранить новый образ:
$ docker build -t shykes/myapp .
Чтобы пометить образ как несколько репозиториев после сборки, добавьте несколько репозиториев при запуске команды сборки.-t
параметр:
$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .
Демоны Docker запускаются один за другимDockerfile
Инструкции в , при необходимости фиксируют результат каждой инструкции в новом изображении и, наконец, выводят идентификатор нового изображения. Демон Docker автоматически очистит отправляемый вами контекст.
Обратите внимание, что каждая инструкция выполняется независимо и приводит к созданию нового образа.RUN cd / tmp
Это не повлияет на следующую команду.
По возможности Docker будет повторно использовать промежуточные образы (кеши) для значительного ускорения.docker build
процесс.这由控制台输出中的使用缓存消息指示。 (有关详细信息,请参阅Dockerfile
Руководящие принципы передового опытаРаздел кеша сборки):
$ docker build -t svendowideit/ambassador .
Sending build context to Docker daemon 15.36 kB
Step 1 : FROM alpine:3.2
---> 31f630c65071
Step 2 : MAINTAINER SvenDowideit@home.org.au
---> Using cache
---> 2a1c91448f5f
Step 3 : RUN apk update && apk add socat && rm -r /var/cache/
---> Using cache
---> 21ed6e7fbb73
Step 4 : CMD env | grep _TCP= | (sed 's/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat -t 100000000 TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&/' && echo wait) | sh
---> Using cache
---> 7ea8aef582cc
Successfully built 7ea8aef582cc
После успешной сборки можно подготовитьPushing a repository to its registry.
Format
Dockerfile
Формат следующий:
# Comment
INSTRUCTION arguments
INSTRUCTION
Он не чувствителен к регистру, но рекомендуется использовать верхний регистр.
Dockerfile中的指令第一个指令必需是
FROM`, укажите образ сборкиBase Image.
Dockerfile начинается с#
Строки в начале обрабатываются как комментарии, если только они не являются директивами парсера [директивы парсера](). Последовательные символы комментариев не поддерживаются.
# Comment
RUN echo 'we are running some # of cool things'
Parser directives
Директивы парсера являются необязательными и влияют на обработкуDockerfile
Путь следования посередине. Директивы парсера не добавляют слоев в сборку и не отображаются в шагах сборки. Директива парсера# directive = value
Форма написана как особый тип комментария. Одна инструкция может быть использована только один раз.
После того, как комментарии, пустые строки или директивы построителя были обработаны, Docker больше не ищет директивы парсеров. Вместо этого он относится к любому отформатированному анализатору директивы как комментарий, и не пытается убедиться, что это может быть директива парсера. Поэтому все директивы парсеров должны быть расположены вDockerfile
самый верх.
Директивы парсера не чувствительны к регистру. Однако по соглашению они пишутся в нижнем регистре. Соглашение также включает пустую строку после любых директив синтаксического анализатора. Директива парсера не поддерживает символы продолжения строки.
Из-за этих правил ни один из следующих примеров не является допустимым:
Недействительно из-за продолжения строки:
# direc \
tive=value
Недействительно, потому что встречается дважды:
# directive=value1
# directive=value2
FROM ImageName
Поскольку он написан после инструкции по сборке, он недействителен:
FROM ImageName
# directive=value
Недействительно, потому что это не написано после директивы парсера:
# About my dockerfile
FROM ImageName
# directive=value
Неизвестная директива считается комментарием, и следующие инструкции парсера также недействительны:
# unknowndirective=value
# knowndirective=value
В директивах парсера разрешены пробелы без новой строки, следующие строки считаются одинаковыми:
#directive=value
# directive =value
# directive= value
# directive = value
# dIrEcTiVe=value
Парсер поддерживает следующие команды: * Escape
escape
# escape=\ (backslash)
或者
# escape=` (backtick)
escape
Инструкции установлены для использования вDockerfile
символ в escape-символах. Если не указано, escape-символом по умолчанию является\
.
Экранирующие символы используются как для экранирования символов в строке, так и для экранирования новых строк. Это позволяетDockerfile
Инструкции охватывают несколько строк. Обратите внимание, что не важноescape
Включены ли директивы парсера вDockerfile
в, вRUN
В команде не выполняется экранирование, кроме как в конце строки.
Установите escape-символ на `inWindows
особенно полезно на\
Это разделитель пути к каталогу. `ИWindows PowerShellПоследовательный.
Рассмотрим следующий пример, которыйWindows
Вышеприведенное терпит неудачу неочевидным образом. второй в конце второй строки\
будет интерпретироваться как новая строка, а не с первой\
Цель побега. Точно так же предположим, что в конце третьей строки\
На самом деле обрабатывается как одна инструкция, она будет рассматриваться как продолжение строки. этоdockerfile
Результатом является то, что вторая линия и третьи линии считаются одной инструкцией:
FROM windowsservercore
COPY testfile.txt c:\\
RUN dir c:\
оказаться:
PS C:\John> docker build -t cmd .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM windowsservercore
---> dbfee88ee9fd
Step 2 : COPY testfile.txt c:RUN dir c:
GetFileAttributesEx c:RUN: The system cannot find the file specified.
PS C:\John>
Одним из решений вышеизложенного является использование/
в видеCOPY
инструкция иdir
Цель. Однако этот синтаксис в лучшем случае сбивает с толку, потому что онWindows
это необычный путь и в худшем случае подверженный ошибкам, потому что он неWindows
Все команды включены/
Как разделитель пути.
Благодаря добавлению директив escape-парсера следующий файл Dockerfile успешно работает в Windows, используя естественную семантику путей к файлам платформы:
# escape=`
FROM windowsservercore
COPY testfile.txt c:\
RUN dir c:\
оказаться:
PS C:\John> docker build -t succeeds --no-cache=true .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM windowsservercore
---> dbfee88ee9fd
Step 2 : COPY testfile.txt c:\
---> 99ceb62e90df
Removing intermediate container 62afbe726221
Step 3 : RUN dir c:\
---> Running in a5ff53ad6323
Volume in drive C has no label.
Volume Serial Number is 1440-27FA
Directory of c:\
03/25/2016 05:28 AM <DIR> inetpub
03/25/2016 04:22 AM <DIR> PerfLogs
04/22/2016 10:59 PM <DIR> Program Files
03/25/2016 04:22 AM <DIR> Program Files (x86)
04/18/2016 09:26 AM 4 testfile.txt
04/22/2016 10:59 PM <DIR> Users
04/22/2016 10:59 PM <DIR> Windows
1 File(s) 4 bytes
6 Dir(s) 21,252,689,920 bytes free
---> 2569aa19abef
Removing intermediate container a5ff53ad6323
Successfully built 2569aa19abef
PS C:\John>
Environment replacement
переменные окружения (используяENVобъявление оператора) также может использоваться в некоторых директивах какDockerfile
Объясните переменную. Вы также можете обработать побег, чтобы включить в инструкцию синтаксис подобных переменных.
переменная окружения вDockerfile
С участием$variable_name
или${variable_name}
Выражать. Они обрабатываются одинаково, и синтаксис квадратных скобок часто используется для разрешения имен переменных без пробелов, например.${foo}_bar
.
${variable_name}
Грамматика также поддерживает некоторые стандарты, указанные ниже.bash
Модификатор:
-
${variable:-word}
Указывает, что если установленоvariable
,则结果将是该值。 еслиvariable
не установлено,word
будет результат. -
${variable:+word}
Указывает, что если установленоvariable
,Такword
будет результатом, иначе результатом будет пустая строка.
Во всех ситуациях,word
Может быть любая строка, включая дополнительные переменные среды.
Добавляя перед переменной\
Сбежать:\$foo
или\${foo}
, которые преобразуются в$foo
и${foo}
.
Пример (разобранное представление показано на#
позже):
FROM busybox
ENV foo /bar
WORKDIR ${foo} # WORKDIR /bar
ADD . $foo # ADD . /bar
COPY \$foo /quux # COPY $foo /quux
Dockerfile
Следующий список инструкций поддерживает переменные среды:
- ADD
- COPY
- ENV
- EXPOSE
- LABEL
- USER
- WORKDIR
- VOLUME
- STOPSIGNAL
а также:
- ONBUILD (в сочетании с одной из поддерживаемых выше инструкций)
注意
: До 1.4,ONBUILD
Директивы не поддерживают переменные среды, даже в сочетании с любой из перечисленных выше директив.
Подстановка переменных среды будет использовать одно и то же значение для каждой переменной во всей команде. Другими словами, в этом примере:
ENV abc=hello
ENV abc=bye def=$abc
ENV ghi=$abc
Быть вызваннымdef
Ценностьhello
,больше никогдаbye
. Тем не мение,ghi
значениеbye
, потому что он не установленabc
заbye
часть той же команды.
.dockerignore file
Прежде чем Docker CLI отправляет контекст до Docker Daemon, он смотрит в корневой каталог контекста для каталога с именем.dockerignore
документ. Если этот файл существует, CLI изменит контекст, чтобы исключить файлы и каталоги, соответствующие шаблону в нем. Это помогает избежать ненужной отправки больших или конфиденциальных файлов и каталогов демону и может использоватьADD
илиCOPY
Добавьте его к изображению.
CLI будет.dockerignore
Файл интерпретируется как список шаблонов, разделенных новой строкой, как в Unix.shell
файловые шары. В целях сопоставления корень контекста считается рабочим каталогом и корневым каталогом. Например, узор/foo/bar
иfoo/bar
все исключеноPATH
изfoo
подкаталоги с именемbar
файл или каталог, или находится вURL
в корневом каталоге репозитория git по адресу . Он также не исключает каких-либо других.
если.dockerignore
Строка файла до столбца 1 до#
В начале линия считается комментарием и игнорируется до объяснения CLI.
Вот пример.dockerignore
документ:
# comment
*/temp*
*/*/temp*
temp?
Этот файл приводит к следующему поведению сборки:
правило | поведение |
---|---|
# comment |
пренебрегать |
*/temp* |
Исключает файлы и каталоги, имена которых начинаются с temp в любом непосредственном подкаталоге корня. Например, обычный файл /somedir/temporary.txt исключается, как и каталог /somedir/temp. |
*/*/temp* |
Файлы и каталоги, начиная с TEMP, исключаются из любых подкаталогов на два уровня ниже корневого каталога. Например, /somedir/subdir/temporary.txt исключен. |
temp? |
Исключите файлы и каталоги с односимвольным расширением с именем temp в корневом каталоге. Например, /tempa и /tempb исключаются. |
Сопоставление выполняется с помощью Gofilepath.MatchПравила выполнены. Шаг предварительной обработки удаляет начальные и конечные пробелы и устраняет.
и..
элементы с использованием Gofilepath.Clean. Пустые строки после предварительной обработки игнорируются.
В дополнение к правилам Go filepath.match, Docker также поддерживает специальную строку с подстановочными знаками.**
, который соответствует любому количеству каталогов (включая ноль). Например,**/*.go
исключит все каталоги, найденные в.go
Все файлы в конце, включая корень контекста сборки.
начало строки!
(восклицательный знак) можно использовать для исключения исключений. Ниже приводится использование этого механизма.dockerignore
Файл:
*.md
!README.md
КромеREADME.md
Все внешние файлы уценки исключаются из контекста.
место!
Правило исключения влияет на поведение: соответствует определенному файлу.dockerignore
Последняя строка определяет, включен он или исключен. Рассмотрим следующий пример:
*.md
!README*.md
README-secret.md
КромеREADME-secret.md
за пределамиREADME
файл, все файлы уценки исключаются из контекста.
Теперь рассмотрим этот пример:
*.md
README-secret.md
!README*.md
Включите все файлы README. Средняя линия не имеет значения, потому что последняя!README*.md
иREADME-secret.md
совпадение.
Вы даже можете использовать.dockerignore
файл для исключенияDockerfile
и.dockerignore
документ. Эти файлы по-прежнему отправляются демону, потому что они нужны ему для выполнения своей работы. ноADD
иCOPY
команда не копирует их в образ.
Наконец, вам может понадобиться указать файлы для включения в контекст, а не файлы для исключения. Для этого укажите*
в качестве первого шаблона, за которым следует один или несколько!
режим исключения.
注意
: по историческим причинам.
модель. быть проигнорировано.
FROM
FROM <image>
# 或则
FROM <image>:<tag>
# 或则
FROM <image>@<digest>
FROM
Инструкции установлены для последующих инструкцийBase Image. Следовательно, эффективноеDockerfile
должен иметьFROM
как его первая инструкция. изображение может быть любым допустимым изображением - может быть получено изPublic Repositoriespulling an image.
-
FROM
должно бытьDockerfile
Первая неиндукционная команда. -
FROM
доступны в одномDockerfile
появляется несколько раз для создания нескольких изображений. Просто делайте заметки о каждом новомFROM
Идентификатор последнего изображения, выдаваемый фиксацией перед командой. -
tag
илиdigest
является необязательным. Если какой-либо из них опущен, сборщик по умолчанию будет использоватьlatest
. Если застройщик сtag
Значения не совпадают, тогда билдер вернет ошибку.
MAINTAINER
MAINTAINER <name>
MAINTAINER
Директива позволяет вам установить поле автора сгенерированных изображений.
RUN
RUN имеет 2 формы:
-
RUN <command>
(форма *shell*, команда запускается в оболочке, в Linux это/bin/sh -c
, на окнах какcmd /S/C
) -
RUN ["executable","param1","param2"]
(execформа)
RUN
Директива выполнит любую команду в новом слое поверх текущего изображения и зафиксирует результат. Полученный зафиксированный образ будет использоваться дляDockerfile
следующий шаг в .
СлоистыйRUN
Директивы и генерация коммитов соответствуют основным концепциям Docker, где коммиты легковесны, а контейнеры можно создавать из любой точки истории образа, как и в системе управления версиями.
exec
Форма позволяет избежать изменений строки оболочки и запускать с базовым образом, который не содержит указанный исполняемый файл оболочки.RUN
Заказ.
можно использоватьSHELL
Команда для изменения оболочки по умолчанию для форм оболочки.
В форме оболочки вы можете использовать\
(обратная косая черта) будет одинарнымRUN
Инструкция продолжается до следующей строки. Например, рассмотрим эти две строки:RUN /bin/bash -c 'source $HOME/.bashrc ; \ echo $HOME'
Они эквивалентны этой строке:RUN /bin/bash -c 'source $HOME/.bashrc ; echo $HOME'
注意
: Чтобы использовать другую оболочку, чем '/bin/sh', используйте форму exec, переданную в нужной оболочке. Например, RUN ["/bin/bash", "-c", "echo hello"]
注意
Форма :exec анализируется как массив JSON, что означает, что вы должны использовать двойные кавычки (") вместо одинарных кавычек (') за пределами слов.
注意
: В отличие от формы оболочки, форма exec не вызывает командную оболочку. Это означает, что нормальная обработка оболочки не происходит. Например,RUN ["echo","$HOME"]
не будет там$HOME
замена переменной на . Если вам нужна обработка оболочки, используйте форму оболочки или запустите оболочку напрямую, например:RUN ["sh","-c","echo $HOME"]
. При использовании формы exec и непосредственном выполнении оболочки, как и в случае с формой оболочки, расширение переменной среды выполняет оболочка, а не docker.
注意
: В форме JSON необходимо экранировать обратную косую черту. Это особенно актуально в Windows, где обратная косая черта является разделителем пути. Поскольку это недопустимый JSON и происходит непредвиденный сбой, следующая строка будет рассматриваться как форма оболочки:RUN ["c:\windows\system32\tasklist.exe"]
Правильный синтаксис для этого примера:RUN ["c:\\windows\\system32\\tasklist.exe"]
используется дляRUN
指令的高速缓存在下一次构建期间不会自动失效。 Для такихRUN apt-get dist-upgrade
之类的指令的高速缓存将在下一次构建期间被重用。 можно сделать с помощью--no-cache
знак для использованияRUN
Кеширование недействительных инструкций, таких какdocker build --no-cache
.
Для получения дополнительной информации см.Руководство по лучшим практикам Dockerfile.
используется дляRUN
Доступ к кэшу инструкций можно получить черезADD
Команда недействительна. Для получения дополнительной информации см.ниже.
Известные проблемы (ЗАПУСК)
-
Issue 783Это о проблемах разрешений на файл, которые могут возникнуть при использовании файловой системы AUFS. Например, вы можете попробовать
rm
файл, заметив это. Для систем с последней версией aufs (т.е. можно установитьdirperm1
вариант установки), докер попытается установить с помощьюdirperm1
Возможность установки образа для автоматического решения проблемы. Связанныйdirperm1
Дополнительные сведения об опциях см.справочная страница aufsЕсли ваша система не поддерживаетdirperm1
Проблема описана в решении.
CMD
Существует три формы инструкций CMD:
-
CMD ["executable","param1","param2"]
(execформа, предпочтительная форма) -
CMD ["param1","param2"]
(as default parameters toENTRYPOINT) -
CMD command param1 param2
(shellform)
существуетDockerfile
только один изCMD
инструкция. Если вы перечислите более одногоCMD
Только последнийCMD
вступит в силу.
CMD
Основная цель — предоставить значения по умолчанию для контейнера выполнения. Эти значения по умолчанию могут включать исполняемые файлы или исключать исполняемые файлы, и в этом случае вы также должны указатьENTRYPOINT
инструкция.
注意
: при использованииCMD
заENTRYPOINT
директива предоставляет параметры по умолчанию,CMD
иENTRYPOINT
Директивы должны быть указаны в формате массива JSON.
注意
Форма :exec анализируется как массив JSON, что означает, что вы должны использовать двойные кавычки (") вместо одинарных кавычек (') за пределами слов.
注意
: В отличие от формы оболочки, форма exec не вызывает командную оболочку. Это означает, что нормальная обработка оболочки не происходит. Например,CMD ["echo","$HOME"]
не будет там$HOME
замена переменной на . Если вам нужна обработка оболочки, используйте форму оболочки или запустите оболочку напрямую, например:CMD ["sh","-c","echo $HOME"]
. При использовании формы exec и непосредственном выполнении оболочки, как и в случае с формой оболочки, расширение переменной среды выполняет оболочка, а не docker.
При использовании в формате оболочки или execCMD
Директива устанавливает команду для выполнения при запуске образа.
При использованииCMD
форма оболочки, затем<command>
будет/bin/sh -c
Выполнить через:
FROM ubuntu
CMD echo "This is a test." | wc -
Если вы хотите запустить свой<command>
Без оболочки вы должны представить команду в виде массива JSON и указать полный путь к исполняемому файлу. Эта форма массиваCMD
предпочтительный формат. Любые другие аргументы должны быть представлены индивидуально в виде строк в массиве:
FROM ubuntu
CMD ["/usr/bin/wc","--help"]
Если вы хотите ваш контейнер каждый раз, когда вы запускаете тот же исполняемый файл, то вам следует рассмотреть возможность использования комбинации enterPoint CMD. видетьENTRYPOINT.
Если пользователь указываетdocker run
Параметры, то они будут покрыватьCMD
Значение по умолчанию, указанное в .
注意
:Не надоRUN
иCMD
Смущенный.RUN
фактически запустить команду и отправить результат;CMD
Ничего не делайте во время сборки, но укажите ожидаемую команду для образа.
LABEL
LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL
Директива для добавления метаданных к изображению.LABEL
является парой ключ-значение. быть вLABEL
Значения содержат пробелы, используйте кавычки и обратную косую черту, как при разборе командной строки. Несколько примеров использования:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \
that label-values can span multiple lines."
Изображение может иметь несколько ярлыков. Чтобы указать несколько ярлык, Docker рекомендует включать теги на одинLABEL
Директива. каждыйLABEL
Директива создает новый слой, что может привести к неэффективным изображениям, если используется много меток. В этом примере создается один слой изображения.
LABEL multi.label1="value1" multi.label2="value2" other="value3"
Вышеупомянутое также может быть записано как:
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"
Добавлены теги, в том числеLABEL
существуетFROM
картинки. Если Docker обнаружит уже существующую метку/ключ, новое значение перезапишет любую предыдущую метку с тем же ключом.
Чтобы просмотреть метки изображения, используйтеdocker inspect
Заказ.
"Labels": {
"com.example.vendor": "ACME Incorporated"
"com.example.label-with-value": "foo",
"version": "1.0",
"description": "This text illustrates that label-values can span multiple lines.",
"multi.label1": "value1",
"multi.label2": "value2",
"other": "value3"
},
EXPOSE
EXPOSE <port> [<port>...]
EXPOSE
Директива указывает контейнеру Docker прослушивать указанный сетевой порт во время выполнения.EXPOSE
Не делайте порт контейнера хоста доступным. Для этого необходимо использовать-p
флаг, чтобы опубликовать диапазон портов, или использовать-P
Отметьте, чтобы опубликовать все открытые порты. Вы можете предоставить один номер порта и опубликовать его снаружи с другим номером порта.
Чтобы настроить перенаправление порта на хост-системе, см.Используйте знак -p. Docker网络功能支持创建网络,无需在网络中公开端口,有关详细信息,请参阅Обзор этой функции).
ENV
ENV <key> <value>
ENV <key>=<value> ...
ENV
директива для установки переменных окружения<key>
установить значение<value>
. Это значение будет всем «потомком»Dockerfile
командную среду и может использоваться во многихзаменить на встроенный.
ENV
Инструкции бывают двух видов. первая форма,ENV <key> <value>
, который устанавливает одну переменную в значение. Вся строка после первого пробела будет рассматриваться как<value>
- включить символы, такие как пробелы и кавычки.
вторая форма,ENV <key> = <value> ...
, что позволяет одновременно задавать несколько переменных. Обратите внимание, что вторая форма использует в синтаксисе знак равенства (=), а первая форма — нет. Подобно анализу командной строки, кавычки и обратную косую черту можно использовать для включения пробелов в значение.
Например:
ENV myName="John Doe" myDog=Rex\ The\ Dog \
myCat=fluffy
# 和
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy
Такого же чистого результата будет производиться в окончательном контейнере, но первая форма является предпочтительной, поскольку она производит один слой кэша.
использоватьENV
Набор переменных среды будет сохранен при запуске контейнера из полученного образа. ты можешь использовать этоdocker inspect
Смотрите значение и использоватьdocker run --env <key> = <value>
изменить их.
注意
: Стойкость в окружающей среде может вызвать неожиданные побочные эффекты. Например, будетENV DEBIAN_FRONTEND
Установка неинтерактивного режима может запутать пользователей apt-get с образами на основе Debian. Чтобы установить значение для одной команды, используйтеRUN <key> = <value> <command>
.
ADD
Две формы:
ADD <src>... <dest>
-
ADD ["<src>",... "<dest>"]
(Эта форма необходима для путей, содержащих пробелы)
ADD
инструкция от<src>
Скопируйте новые файлы, каталоги или удаленные файлыURL
и добавьте их в файловую систему контейнера, путь<dest>
.
Можно указать несколько<src>
ресурсы, но если это файлы или каталоги, то они должны относиться к создаваемому исходному каталогу (контекст сборки).
каждый<src>
Может содержать подстановочные знаки, при сопоставлении будет использоваться Gofilepath.MatchПравила завершены. Например:
ADD hom* /mydir/ # adds all files starting with "hom"
ADD hom?.txt /mydir/ # ? is replaced with any single character, e.g., "home.txt"
<dest>
является абсолютным путем или относительнымWORKDIR
Путь, по которому будет скопирован источник в целевом контейнере.
ADD test relativeDir/ # adds "test" to `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # adds "test" to /absoluteDir/
Все новые файлы и каталоги печатаются с использованием созданного UID и GID 0.
существует<src>
это удаленный файлURL
, цель будет иметь 600 разрешений. Если извлекаемый удаленный файл имеет HTTPLast-Modified
заголовок, отметка времени из этого заголовка будет использоваться для установкиmtime
документ. Однако, как и вADD
как и любой другой файл, обрабатываемый во времяmtime
Не будет учитываться при определении того, изменился ли файл и следует ли обновить кеш.
注意
: если, передавDockerfile
через стандартный ввод (docker build - <somefile
) строится без контекста сборки, поэтомуDockerfile
может содержать только один основанный на URLADD
инструкция. Вы также можете передавать сжатые архивы через STDIN :(docker build - <archive.tar.gz
), в корневом каталоге архиваDockerfile
а остальная часть архива будет использоваться в контексте сборки.
注意
: если ваш URL-файл защищен аутентификацией, вам необходимо использоватьRUN wget
,RUN curl
Или используйте другие инструменты внутри контейнера, так как инструкция ADD не поддерживает аутентификацию.
注意
:если<src>
Содержание изменено, впервые встретившеесяADD
Инструкции будут исходить отDockerfile
的所有后续指令的高速缓存无效。这包括使用于RUN指令的高速缓存无效。 Для получения дополнительной информации см.Руководство по лучшим практикам Dockerfile.
ADD
Соблюдайте следующие правила:
-
<src>
Путь должен быть в контексте сборки; вы не можетеADD ../something /something
, потому что первым шагом сборки докера является отправка каталога контекста (и подкаталогов) демону докера. если<src>
URL-адрес и<dest>
не заканчивается косой чертой, загрузите файл с URL-адреса и скопируйте его в<dest>
. - если
<src>
URL-адрес и<dest>
заканчивается косой чертой, имя файла выводится из URL-адреса, и файл загружается в<dest>/<filename>
. Например,ADD http://example.com/foobar /
создаст файл/ foobar
. URL-адрес должен иметь нетривиальный путь, чтобы в этом случае можно было найти подходящее имя файла (http://example.com
Она не будет работать). - если
<src>
Это каталог, скопируйте все содержимое каталога, включая метаданные файловой системы.
注意
: Сам каталог не копируется, только его содержимое.
- если
<src>
представляет собой локальный tar-архив в распознаваемом формате сжатия (identity, gzip, bzip2 или xz), распакуйте его как каталог. Ресурсы с удаленных URL-адресов не распаковываются. Когда каталог копируется или распаковывается, он имеет тот жеtar -x
То же поведение: результатом является объединение:- как на пути назначения, так и
- Содержимое исходного дерева анализируется как «2.» на основе одного за другим.
注意
: Распознается ли файл как признанный формат сжатия, основываясь только на содержимом файла, а не на имени файла. Например, если пустой файл заканчивается на .tar.gz, он не будет распознан как сжатый файл и не будет генерировать никаких сообщений об ошибках распаковки, а файл будет просто скопирован в место назначения.
- если
<src>
любой другой тип файла, который копируется отдельно со своими метаданными. В этом случае, если<dest>
с косой чертой в конце/
заканчивается, он будет считаться каталогом, и<src>
Контент будет написан на<dest>/base(<src>)
. - Если более одного указано напрямую или из-за использования подстановочных знаков
<src>
ресурсы, то<dest>
Должен быть каталогом и должен заканчиваться косой чертой/
конец. - если
<dest>
не заканчивается косой чертой, он будет рассматриваться как обычный файл,<src>
Контент будет написан на<dest>
. - если
<dest>
не существует, он будет создан со всеми отсутствующими каталогами на своем пути.
COPY
Две формы:
COPY <src>... <dest>
-
COPY ["<src>",... "<dest>"]
(this form is required for paths containing whitespace)
В основном похоже на добавление, ноCOPY
из<src>
Не может быть URL.
ENTRYPOINT
Две формы:
- ENTRYPOINT ["исполняемый", "парам1", "парам2"] (execформа, предпочтительнее)
- ENTRYPOINT command param1 param2 (shellформа)
ENTRYPOINT
Позволяет настроить контейнеры для запуска исполняемых файлов.
Например, следующее запустит nginx с содержимым по умолчанию, прослушивая порт 80:
docker run -i -t --rm -p 80:80 nginx
docker run <image>
Аргументы командной строки будут добавлены в
ENTRYPOINT
после того, как все элементы будут переопределены с помощьюCMD
Все указанные элементы. Это позволяет передавать параметры в точку входа, то есть.docker run <image> -d
положит-d
Аргументы передаются в точку входа. ты можешь использовать этоdocker run --entrypoint
наложение логотипаENTRYPOINT
инструкция.
CMD
Или запустить аргументы командной строки, но недостаток выENTRYPOINT
Сделаю/bin/sh -c
Подкоманд начинается, он не проходит сигналы. Это означает, что исполняемый файл не будет контейнеромPID 1
, и не будет получать сигналы Unix, поэтому ваш исполняемый файл не запустится сdocker stop <container>
получилаSIGTERM
.
ТолькоDockerfile
ПоследнийENTRYPOINT
Инструкция будет иметь эффект.
Exec form ENTRYPOINT example
ты можешь использовать этоENTRYPOINT
Форма *exec* устанавливает довольно стабильные команды и аргументы по умолчанию, а затем использует любую формуCMD
Установите другие значения по умолчанию, которые, скорее всего, будут изменены.
FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
При запуске контейнера видно, что top — единственный процесс:
$ docker run -it --rm --name test top -H
top - 08:25:00 up 7:27, 0 users, load average: 0.00, 0.01, 0.05
Threads: 1 total, 1 running, 0 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.1 us, 0.1 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 2056668 total, 1616832 used, 439836 free, 99352 buffers
KiB Swap: 1441840 total, 0 used, 1441840 free. 1324440 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 19744 2336 2080 R 0.0 0.1 0:00.04 top
Для дальнейшей проверки результатов вы можете использоватьdocker exec
:
$ docker exec -it test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 2.6 0.1 19752 2352 ? Ss+ 08:24 0:00 top -b -H
root 7 0.0 0.1 15572 2164 ? R+ 08:25 0:00 ps aux
И вы можете изящно проситьtop
использоватьdocker stop test
закрытие.
следующееDockerfile
показать использованиеENTRYPOINT
бежать на переднем планеApache
(т.е. какPID 1
):
FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
Если вам нужно написать сценарий запуска для одного исполняемого исполняемого файла, вы можете использоватьexec
иgosu
Команда гарантирует, что окончательный исполняемый файл получит сигналы Unix:
#!/bin/bash
set -e
if [ "$1" = 'postgres' ]; then
chown -R postgres "$PGDATA"
if [ -z "$(ls -A "$PGDATA")" ]; then
gosu postgres initdb
fi
exec gosu postgres "$@"
fi
exec "$@"
Наконец, если вам нужно выполнить дополнительную очистку при завершении работы (или связаться с другими контейнерами) или координировать несколько исполняемых файлов, вы можете убедиться, чтоENTRYPOINT
Скрипт получает Unix-сигналы, передает их дальше и выполняет дополнительную работу:
#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too
# USE the trap if you need to also do manual cleanup after the service is stopped,
# or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM
# start service in background here
/usr/sbin/apachectl start
echo "[hit enter key to exit] or run 'docker stop <container>'"
read
# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stop
echo "exited $0"
если вы используетеdocker run -it --rm -p 80:80 --name test apache
Запустите изображение, вы можете использовать · Docker Exec · или · Docker Top · Процесс проверки контейнера, затем скрипт запроса Apache:
$ docker exec -it test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 4448 692 ? Ss+ 00:42 0:00 /bin/sh /run.sh 123 cmd cmd2
root 19 0.0 0.2 71304 4440 ? Ss 00:42 0:00 /usr/sbin/apache2 -k start
www-data 20 0.2 0.2 360468 6004 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
www-data 21 0.2 0.2 360468 6000 ? Sl 00:42 0:00 /usr/sbin/apache2 -k start
root 81 0.0 0.1 15572 2140 ? R+ 00:44 0:00 ps aux
$ docker top test
PID USER COMMAND
10035 root {run.sh} /bin/sh /run.sh 123 cmd cmd2
10054 root /usr/sbin/apache2 -k start
10055 33 /usr/sbin/apache2 -k start
10056 33 /usr/sbin/apache2 -k start
$ /usr/bin/time docker stop test
test
real 0m 0.27s
user 0m 0.03s
sys 0m 0.03s
注意
: вы можете использовать его--entrypoint
обложкаENTRYPOINT
set, но это только устанавливает двоичный файл в *exec* (не используйтеsh -c
).
注意
Форма :*exec* анализируется как массив JSON, что означает, что вы должны использовать двойные кавычки (") вместо одинарных кавычек (') за пределами слов.
注意
:иshell
В отличие от формы, форма *exec* не вызывает командную оболочку. Это означает, что нормальная обработка оболочки не происходит. Например,ENTRYPOINT ["echo","$ HOME"]
не будет там$HOME
замена переменной на . Если вам нужна обработка оболочки, используйте форму оболочки или запустите оболочку напрямую, например:ENTRYPOINT ["sh","-c","echo $HOME"]
. При использовании формы exec и непосредственном выполнении оболочки, как и в случае с формой оболочки, расширение переменной среды выполняет оболочка, а не docker.
Shell form ENTRYPOINT example
ты сможешьENTRYPOINT
Укажите простую строку, она будет в/bin/sh -c
в исполнении. Эта форма будет использовать обработку оболочки для замены переменных среды оболочки и будет игнорировать любыеCMD
илиdocker run
Параметры командной строки. Для обеспеченияdocker stop
будет корректно испускать любые длительныеENTRYPOINT
исполняемый, вам нужно помнить, чтобы использоватьexec
Начни это:
FROM ubuntu
ENTRYPOINT exec top -b
При запуске этого образа вы увидите одинPID 1
процесс:
$ docker run -it --rm --name test top
Mem: 1704520K used, 352148K free, 0K shrd, 0K buff, 140368121167873K cached
CPU: 5% usr 0% sys 0% nic 94% idle 0% io 0% irq 0% sirq
Load average: 0.08 0.03 0.05 2/98 6
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
1 0 root R 3164 0% 0% top -b
это награда вdocker stop
Чистый выход:
$ /usr/bin/time docker stop test
test
real 0m 0.20s
user 0m 0.02s
sys 0m 0.04s
Если вы забудетеexec
добавить в свойENTRYPOINT
начало:
FROM ubuntu
ENTRYPOINT top -b
CMD --ignored-param1
Затем вы можете запустить его (далее дайте ему имя):
$ docker run -it --name test top --ignored-param2
Mem: 1704184K used, 352484K free, 0K shrd, 0K buff, 140621524238337K cached
CPU: 9% usr 2% sys 0% nic 88% idle 0% io 0% irq 0% sirq
Load average: 0.01 0.02 0.05 2/101 7
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
1 0 root S 3168 0% 0% /bin/sh -c top -b cmd cmd2
7 1 root R 3164 0% 0% top -b
Вы можете видеть из вывода top, что указанная ENTRYPOINT не является PID 1.
Если вы затем запустите тест остановки докера, контейнер не выйдет полностью — команда остановки заставит отправить SIGKILL по истечении времени ожидания:
$ docker exec -it test ps aux
PID USER COMMAND
1 root /bin/sh -c top -b cmd cmd2
7 root top -b
8 root ps aux
$ /usr/bin/time docker stop test
test
real 0m 10.19s
user 0m 0.04s
sys 0m 0.03s
Understand how CMD and ENTRYPOINT interact
CMD
иENTRYPOINT
Директивы определяют, какие команды выполнять при запуске контейнера. Здесь меньше правил, описывающих их сотрудничество.
-
Dockerfile
следует указать хотя бы одинCMD
илиENTRYPOINT
Заказ. - При использовании контейнера в качестве исполняемого файла необходимо определить
ENTRYPOINT
. -
CMD
следует использовать в качестве определенияENTRYPOINT
Аргументы по умолчанию для команды или способ выполнения специальных команд в контейнере. - При запуске контейнера с параметрами подстановки
CMD
Это будет перезаписано.
В таблице ниже показаны разныеENTRYPOINT
/CMD
Команды, выполняемые в комбинации:
no ENTRYPOINT | ENTRYPOINT exec_enty p1_entry | ENTRYPOINT ["exec_entry", "p1_entry"] | |
---|---|---|---|
No CMD | error, not allowed | /bin/sh -c exec_entry p1_entry | exec_entry p1_entry |
cmd["exec_cmd", "p1_cmd"] | exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry exec_cmd p1_cmd | exec_entry p1_entry exec_cmd p1_cmd |
CMD ["p1_cmd", "p2_cmd"] | p1_cmd p2_cmd | /bin/sh -c exec_entry p1_entry p1_cmd p2_cmd | exec_entry p1_entry p1_cmd p2_cmd |
CMD exec_cmd p1_cmd | /bin/sh -c exec_cmd p1_cmd | /bin/sh -c exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd | exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd |
VOLUME
VOLUME ["/data"]
VOLUME
Директива создает точку монтирования с указанным именем и помечает ее как зарезервированную для внешних томов с собственного хоста или других контейнеров. Значение может быть массивом JSON.VOLUME ["/var/log/"]
или простая строка с несколькими аргументами, например.VOLUME /var/log
илиVOLUME /var/log /var/db
. Для получения дополнительной информации/примеров и инструкций по установке через клиент Docker см.Общий каталог по объемному документу.
docker run
Команда инициализирует только что созданный том любыми данными, существующими в указанном месте базового образа. Например, рассмотрим следующееDockerfile
Фрагмент:
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
этот Dockerfiledocker run
образ, в/myvol
создать новую точку монтирования наgreeting
Файлы копируются во вновь созданный том.
注意
: Если какой-либо из этапов конструкции данных изменяется в объеме оператора, то эти изменения будут отброшены.
注意
: список анализируется как массив JSON, что означает, что вы должны использовать двойные кавычки (") вместо одинарных кавычек (') вне слов.
USER
USER daemon
USER
Директива устанавливает имя пользователя или UID для использования при запуске образа иDockerfile
в любом ЗАПУСКЕ,CMD
иENTRYPOINT
инструкция.
WORKDIR
WORKDIR /path/to/workdir
WORKDIR
ИнструкцияDockerfile
В любом местеRUN
,CMD
,ENTRYPOINT
,COPY
иADD
指令设置工作目录。 еслиWORKDIR
не существует, он будет создан, даже если его нет ни в одном последующемDockerfile
Используйте в инструкции.
Это может бытьDockerfile
используется несколько раз. Если указан относительный путь, он будет относиться к пути предыдущей инструкции WORKDIR. Например:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
на этоDockerfile
в финалеpwd
Вывод команды/a/b/c
.
WORKDIR
Директивы могут быть предварительно проанализированы с помощьюENV
Переменные среды для установки. Вы можете использовать толькоDockerfile
переменные окружения, явно установленные в . Например:
ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
pwd
команда вDockerfile
Выводится окончательный результат/path/$DIRNAME
.
ARG
ARG <name>[=<default value>]
ARG
Директива определяет переменную, пользователь может использоватьdocker build
Команда--build-arg <varname> = <value>
Флаг передать в строитель в сборке. Если пользователь указываетDockerfile
параметры сборки, определенные в , сборка выдаст ошибку.
One or more build-args were not consumed, failing build.
Авторы Dockerfile могут указыватьARG
Одна или несколько переменных, заданных несколько разARG
для определения одной переменной. Например, действительныйDockerfile
:
FROM busybox
ARG user1
ARG buildno
...
Авторы Dockerfile могут дополнительно указатьARG
Значения по умолчанию для директив:
FROM busybox
ARG user1=someuser
ARG buildno=1
...
еслиARG
Это значение имеет значение по умолчанию, и если во время сборки значение не передается, построитель использует значение по умолчанию.
ARG
Переменные определены изDockerfile
Линия, определенная в зависимости, а не используется в качестве аргумента из командной строки или в другом месте. Например, рассмотрим этот докерфиль:
1 FROM busybox
2 USER ${user:-some_user}
3 ARG user
4 USER $user
...
Пользователи создают этот файл следующим образом:
$ docker build --build-arg user=what_user Dockerfile
строка 2USER
будет оцениваться какsome_user
, потому что пользовательская переменная определена в следующей строке 3. строка 4USER
Оценивается при определении пользователя какwhat_user
, передается в командной строкеwhat_user
ценность. проходя черезARG
Прежде чем инструкция будет определена, использование любой из переменных приведет к пустой строке.
警告
: Не рекомендуется использовать переменные вроде сборки для передачи паролей, таких как клавиши GitHub, учетные данные пользователя и т. Д. Использование регулируемого значенияdocker history
Команды видны любому пользователю образа.
можно использоватьARG
илиENV
указание указатьRUN
Переменные, доступные директиве. использоватьENV
Переменная среды, определенная директивой, всегда переопределяет тот же имяARG
инструкция. думать об этомDockerfile
с участиемENV
иARG
инструкция.
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER v1.0.0
4 RUN echo $CONT_IMG_VER
Затем, предполагая, что этот образ был создан с помощью этой команды:
$ docker build --build-arg CONT_IMG_VER=v2.0.1 Dockerfile
при этих обстоятельствах,RUN
Использование инструкцииv1.0.0
вместо переданного пользователемARG
настраивать:v2.0.1
Это поведение похоже на сценарии оболочки, где переменные с локальной областью действия переопределяют переменные, переданные в качестве аргументов или унаследованные от среды, с точки их определения.
Используя приведенный выше пример, но используя другойENV
спецификации, вы можетеARG
иENV
Создайте более полезные взаимодействия между директивами:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
4 RUN echo $CONT_IMG_VER
иARG
Разные инструкции,ENV
Значение всегда сохраняется в образе. считать нет-build-arg
сборка докера с флагами:
$ docker build Dockerfile
Используя этот пример Dockerfile,CONT_IMG_VER
по-прежнему остается на изображении, но его значение будетv1.0.0
, потому что этоENV
Настройка по умолчанию директивы в строке 3.
Техника переменной экспансии в этом примере позволяет передавать аргументы из командной строки иENV
Директивы сохраняют их на последнем образе. только дляОграниченный набор инструкций Dockerfile поддерживает расширение переменных..
Docker имеет набор предопределенныхARG
переменная, вы можете использовать соответствующую инструкцию ARG в файле Dockerfile.
- HTTP_PROXY
- http_proxy
- HTTPS_PROXY
- https_proxy
- FTP_PROXY
- ftp_proxy
- NO_PROXY
- no_proxy
Чтобы использовать их, просто передайте их в командной строке с флагами:
--build-arg <varname>=<value>
Impact on build caching
ARG
Переменные не сохраняются в построенном образе, потому чтоENV
переменная есть. но,ARG
Аналогичным образом переменные влияют на кеш сборки. еслиDockerfile
определитьARG
переменная, значение которой отличается от значений в предыдущих версиях, то «промах кеша» происходит при ее первом использовании, а не при ее определении. В частности, вARG
все после командыRUN
Все инструкции используют переменную ARG неявно (как переменную среды), поэтому это может привести к промаху кеша.
Например, рассмотрим эти два файла Dockerfile:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 RUN echo $CONT_IMG_VER
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 RUN echo hello
Если указано в командной строке--build-arg CONT_IMG_VER = <value>
Затем в любом случае он не регулирует вторую строку приводу к пропуске кэша; строка 3 приведет к пропущению кэша.ARG CONT_IMG_VER
Привести кRUN
Линия идентифицируется как прогонCONT_IMG_VER = <value> echo hello
то же самое, если<value>
измените, и мы получим промахи кеша.
Рассмотрим другой пример в той же командной строке:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER $CONT_IMG_VER
4 RUN echo $CONT_IMG_VER
В этом примере промах кэша происходит в строке 3. Поскольку переменнаяENV
ссылка на значение вARG
变量并且该变量通过命令行更改,因此发生了未命中。 В этом примереENV
Команда включает изображение, чтобы включить это значение.
еслиENV
Директива переопределяет то же имяARG
инструкции, такие как этот Dockerfile:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER hello
4 RUN echo $CONT_IMG_VER
Строка 3 не вызывает промаха кеша, потому чтоCONT_IMG_VER
Значение является константой (привет). следовательно,RUN
Переменные среды и значения, используемые в (строка 4), не меняются между сборками.
ONBUILD
ONBUILD [INSTRUCTION]
ONBUILD
добавляет к образу директивы *trigger*, которые будут выполняться позже, когда образ будет использоваться в качестве основы для другой сборки. Триггер будет выполняться в контексте нижестоящей сборки, как если бы он был вставлен сразу после инструкции 1FROM1 в нижестоящем Dockerfile.
Любая директива сборки может быть зарегистрирована как триггер.
Это полезно, если вы создаете образ, который будет использоваться в качестве основы для создания других образов, таких как среда сборки приложения или демон, который можно настроить с помощью пользовательской конфигурации.
Например, если ваш образ представляет собой многоразовый конструктор приложений Python, исходный код приложения необходимо добавить в определенный каталог, а после этого может потребоваться вызвать скрипт сборки. ты не можешь просто позвонитьADD
иRUN
Теперь, поскольку у вас нет доступа к исходному коду приложения, он будет отличаться для каждой сборки приложения. Вы можете просто предоставить разработчикам шаблонный файл Dockerfile для копирования и вставки в свои приложения, но это неэффективно, чревато ошибками и сложно обновлять, поскольку оно смешивается с кодом, специфичным для приложения.
Решение заключается в использованииONBUILD
чтобы зарегистрировать предварительную директиву для запуска позже на следующем этапе сборки.
Вот как это работает:
- при встрече
ONBUILD
директивы, сборщик добавляет триггер к метаданным создаваемого образа. Эта директива не влияет на текущую сборку. - В конце сборки список всех триггеров сохраняется в манифесте образа под ключом OnBuild. можно использовать
docker inspect
команда, чтобы проверить их. - Позже вы можете использовать
FROM
Директива использовать образ в качестве основы для новых сборок. как обработкаFROM
часть директивы, которую ищут нижестоящие строителиONBUILD
триггеры и выполнять их в том порядке, в котором они зарегистрированы. Если какой-либо триггер не работает, тоFROM
Инструкция прервалась, что, в свою очередь, привело к сбою сборки. Если все триггеры успешны, тоFROM
Инструкция завершается, и сборка продолжается в обычном режиме. Триггеры очищаются от конечного изображения после выполнения. Другими словами, они не наследуются "внучатскими" сборками. Например, вы можете добавить следующее:[...] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build --dir /app/src [...]
>警告
: не допускаетсяONBUILD ONBUILD
Ссылка на сайтONBUILD
инструкция. >警告
:ONBUILD
Команда может не сработатьFROM
илиMAINTAINER
инструкция.
STOPSIGNAL
STOPSIGNAL signal
STOPSIGNAL
Инструкция устанавливает сигнал системного вызова, который будет отправлен контейнеру для выхода. Сигнал может быть допустимым числом без знака, соответствующим позиции в таблице системных вызовов ядра, например 9, или именем сигнала в формате SIGNAME, например SIGKILL.
HEALTHCHECK
Две формы:
- HEALTHCHECK [ОПЦИИ] Команда CMD (проверьте работоспособность контейнера, выполнив команду в контейнере)
- HEALTHCHECK NONE (отключает любые проверки работоспособности, унаследованные от базового образа)
HEALTHCHECK
Инструкции сообщают Docker, как протестировать контейнер, чтобы проверить, работает ли он. Это может обнаружить такие ситуации, как застревание веб-сервера в бесконечном цикле и невозможность обработки новых подключений, даже если серверный процесс все еще работает.
Когда для контейнера указана проверка работоспособности, он имеет состояние работоспособности в дополнение к своему обычному состоянию. Это состояние изначально начинается. Всякий раз, когда проверка работоспособности проходит успешно, она становится работоспособной (независимо от ее предыдущего состояния). После определенного количества последовательных отказов он становится неработоспособным.
Параметры, которые могут появиться перед CMD:
-
--interval=DURATION
(default: 30s) -
--timeout=DURATION
(default: 30s) -
--retries=N
(default: 3)
Проверка работоспособности сначала запускается после запуска контейнера.intervalсекунд, а затем запускать снова после завершения каждой последней проверкиintervalвторой.
Если один запуск проверки занимает больше времени, чемtimeoutсекунд считается, что проверка не удалась.
это нужноretriesВ случае сбоя непрерывных проверок работоспособности контейнер считается неработоспособным.
В Dockerfile может быть только одинHEALTHCHECK
инструкция. Если вы укажете более одного, только последнийHEALTHCHECK
вступит в силу.
CMD
Команда после того, как ключевое слово может быть командами оболочки (например,HEALTHCHECK CMD /bin/check-running
) или массив execs (как и другие команды Dockerfile; см.ENTRYPOINT
).
Состояние выхода команды указывает на работоспособность контейнера. Возможные значения:
- 0: success - the container is healthy and ready for use
- 1: unhealthy - the container is not working correctly
- 2: reserved - do not use this exit code
Например, чтобы каждые пять минут проверять, может ли веб-сервер обслужить домашнюю страницу веб-сайта за три секунды:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
Чтобы облегчить отладку сбойных зондов, любой выходной текст (в кодировке UTF-8), записанный командой на stdout или stderr, будет сохранен в состоянии работоспособности и может использоваться сdocker inspect
Запрос. Такие выходы должны оставаться закороченными (хранятся только текущие 4096 байт).
При изменении состояния работоспособности контейнера будет создано новое состояние.health_status
событие.
HEALTHCHECK
Функция добавлена в Docker 1.12.
SHELL
SHELL ["executable", "parameters"]
SHELL
Директива позволяет переопределить оболочку по умолчанию формы оболочки, используемой для команды. Оболочка по умолчанию в Linux["/bin/sh","-c"]
, в Windows есть["cmd","/S","/C"]
.SHELL
Инструкции должны быть записаны в Dockerfile в формате JSON.
SHELL
Директивы особенно полезны в Windows, где есть два обычно используемых и совершенно разных местных оболочки:cmd
иpowershell
и включаетsh
альтернативная оболочка.
SHELL
Инструкции могут появляться несколько раз. каждыйSHELL
директива перезаписывает все предыдущиеSHELL
директивы и влияет на все последующие директивы. Например:
FROM windowsservercore
# Executed as cmd /S /C echo default
RUN echo default
# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default
# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello
# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello
Следующие инструкции могут быть затронутыSHELL
Влияние директив, когда их форма оболочки используется в DockerFile:RUN
,CMD
иENTRYPOINT
.
Следующий пример является распространенным режимом в Windows, вы можете использовать инструкцию оболочки для упрощения:
...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...
Командный вызов докера будет:
cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
Это неэффективно по двум причинам. Во-первых, вызывается ненужный командный процессор cmd.exe (он же оболочка). Во-вторых, каждая из оболочекRUN
директивы требуют доп.powershell -command
.
Для большей эффективности можно использовать один из двух механизмов. Один из них — использовать команду RUN в форме JSON, например:
...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...
Хотя форма JSON однозначна и не использует ненужный cmd.exe, она должна быть более подробной с помощью двойных кавычек и экранирования. Альтернативный механизм заключается в использованииSHELL
Директивы и формы оболочки, обеспечивающие более естественный синтаксис для пользователей Windows, особенно сescape
При использовании в сочетании с директивами разборки:
# escape=`
FROM windowsservercore
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'
оказаться:
PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 3.584 kB
Step 1 : FROM windowsservercore
---> 5bc36a335344
Step 2 : SHELL powershell -command
---> Running in 87d7a64c9751
---> 4327358436c1
Removing intermediate container 87d7a64c9751
Step 3 : RUN New-Item -ItemType Directory C:\Example
---> Running in 3e6ba16b8df9
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/2/2016 2:59 PM Example
---> 1f1dfdcec085
Removing intermediate container 3e6ba16b8df9
Step 4 : ADD Execute-MyCmdlet.ps1 c:\example\
---> 6770b4c17f29
Removing intermediate container b139e34291dc
Step 5 : RUN c:\example\Execute-MyCmdlet -sample 'hello world'
---> Running in abdcf50dfd1f
Hello from Execute-MyCmdlet.ps1 - passed hello world
---> ba0e25255fda
Removing intermediate container abdcf50dfd1f
Successfully built ba0e25255fda
PS E:\docker\build\shell>
SHELL
Директивы также можно использовать для изменения способа работы оболочки. Например, в Windows используйтеSHELL cmd /S /C /V:ON|OFF
, который может изменить семантику отложенного раскрытия переменной среды.
SHELL
Инструкции также можно использовать в Linux, если требуется альтернативная оболочка, напримерzsh
,csh
,tcsh
и другие.
SHELL
Функция добавлена в Docker 1.12.
Dockerfile examples
Ниже вы можете увидеть несколько примеров синтаксиса Dockerfile. Если вас интересует что-то более реалистичное, взгляните на пример Dockerization.
# Nginx
#
# VERSION 0.0.1
FROM ubuntu
MAINTAINER Victor Vieux <victor@docker.com>
LABEL Description="This image is used to start the foobar executable" Vendor="ACME Products" Version="1.0"
RUN apt-get update && apt-get install -y inotify-tools nginx apache2 openssh-server
# Firefox over VNC
#
# VERSION 0.3
FROM ubuntu
# Install vnc, xvfb in order to create a 'fake' display and firefox
RUN apt-get update && apt-get install -y x11vnc xvfb firefox
RUN mkdir ~/.vnc
# Setup a password
RUN x11vnc -storepasswd 1234 ~/.vnc/passwd
# Autostart firefox (might not be the best way, but it does the trick)
RUN bash -c 'echo "firefox" >> /.bashrc'
EXPOSE 5900
CMD ["x11vnc", "-forever", "-usepw", "-create"]
# Multiple images example
#
# VERSION 0.1
FROM ubuntu
RUN echo foo > bar
# Will output something like ===> 907ad6c2736f
FROM ubuntu
RUN echo moo > oink
# Will output something like ===> 695d7793cbe4
# You᾿ll now have two images, 907ad6c2736f with /bar, and 695d7793cbe4 with
# /oink.
Создать сведения о файле
Создать файлYAMLфайл для определенияservices,networks, иvolumes. Его путь по умолчанию — ./docker-compose.yml.
Определение службы содержит конфигурацию для всех контейнеров, запущенных службой, что очень похоже на передачу аргументов командной строки команде создания контейнера Docker. Опять же, определения сети и тома аналогичны командам docker network create и docker volume create.
Как и при создании контейнера Docker, параметры, указанные в Dockerfile (например, CMD, EXPOSE, VOLUME, ENV и т. д.), одинаковы, вам не нужно указывать их снова в docker-compose.yml.
1.1. build
Параметры конфигурации, применяемые ко времени сборки
build указывает путь к контексту сборки
В качестве альтернативы его можно указать с помощью класса объекта, содержащего контекст и необязательный файл dockerfile и аргументы.
Если вы также укажете образ при указании сборки, то указанный образ будет использоваться для сборки
1.2. context
Путь к каталогу, содержащему DockerFile, или URL для хранилища Git
Если это значение является относительным путем, то он относительно расположения файла Compose (PS: на самом деле текущий каталог)
1.3. Dockerfile
Вы также можете использовать Dockerfile для сборки, но на этот раз должен быть указан контекст
(PS: DockerFile используется для создания изображений, то есть он может быть построен из изображения или от DockerFile, который одинаково)
1.4. args
Добавьте параметры сборки, доступ к этим переменным среды возможен только в процессе сборки.
Сначала определите переменную в Dockerfile
Затем присвойте значения этим переменным во время сборки
В качестве альтернативы также можно написать следующее
Примечание. Если вы находитесь в Dockerfile, Arg недоступен в директиве FROM.
Вы также можете опустить их значения в параметрах сборки, в этом случае значения будут взяты из среды, в которой запущен Compose (PS: на самом деле это переменная среды)
1.5. cache_from
кешированный список зеркал
1.6. shm_size
Установите размер раздела /dev/shm для этого встроенного контейнера.
1.7. configs
Разрешить службе доступ к конфигурациям, настроенным под ней, с поддержкой двух синтаксисов.
1.7.1 Фразы
Метод фразы указывает только имя config, разрешающее доступ к config контейнеру, и монтирует его в /
В следующем примере служба Redis разрешает доступ к конфигурациям my_config и my_other_config. Значение my_config установлено в ./my_config.txt, а значение my_other_config указывает внешний ресурс, что означает, что значение было определено в Docker.
1.7.2 Длинный синтаксис
Длинный синтаксис обеспечивает более точное управление
- источник: имя конфига
- target : имя файла после монтирования в контейнер, по умолчанию /
- uid и gid: идентификатор владельца и группы файла, монтируемого в контейнер.
- mode : права доступа к файлам, смонтированным в контейнере (PS: если вы не знакомы с режимами разрешений UNIX, вы можете использовать этот инструментpermissions-calculator.org)
В следующем примере будут установлены my_config и redis_config в контейнере, разрешение настройки — 0440, владелец и группа — 103, служба redis не может получить доступ к конфигурации my_other_config.
1.8. container_name
Пользовательское имя контейнера вместо сгенерированного по умолчанию имени
1.9. depends_on
Представляет зависимости между службами, которые приводят к следующему поведению:
- docker-compose up запускает службы в порядке зависимости
- Сервис UPER-COMPOSEP автоматически включает в себя зависимости обслуживания
- docker-compose stop останавливает службы в порядке зависимости
В следующем примере db и redis будут запущены перед веб-сайтом, db и redis также будут созданы и запущены при запуске веб-сайта, а db и redis будут остановлены до остановки веб-сайта.
Примечание: depend_on не будет ждать запуска db и redis перед запуском web.
1.10. deploy
Эта конфигурация действительна только при развертывании в режиме кластера.
1.10.1. mode
глобальные (только один контейнер на узел кластера) или реплицированные (указанное количество контейнеров). По умолчанию реплицируется
1.11. env_file
Добавьте файл переменных среды, который может быть одним значением или списком
Если одна и та же переменная появляется в нескольких файлах, последняя переопределяет предыдущую.
1.12. environment
Добавьте переменную среды, которая может переопределить значение переменной с тем же именем в файле env_file.
1.13. expose
Выставляйте порты, не публикуя их на хосте
1.14. image
Указывает, с какого изображения начинается контейнер, либо идентификатор изображения, либо тег изображения.
1.15. network_mode
сетевой режим
1.16. ports
порт, два синтаксиса
Фраза закон
длинный синтаксис
1.17. restart
Политика перезапуска, по умолчанию нет
1.18. ulimits
Переопределить ulimit контейнера по умолчанию
1.19. volumes
Путь или имя тома узла монтирования
Вы можете смонтировать путь хоста для одной службы, не определяя тома верхнего уровня. Однако если вы хотите, чтобы несколько служб повторно использовали том, это должно быть определено на верхнем уровне.
Фраза
Укажите путь на хосте (хост: контейнер) или режим доступа (хост: контейнер: RO)
(PS: Объясните немного. Например, /opt/data:/var/lib/mysql указывает, что путь для монтирования к хосту — /opt/data, а путь для монтирования к контейнеру — /var/lib /mysql.На самом деле под монтированием можно понимать отображение)
длинный синтаксис
- type : тип монтирования (volume, bind, tmpfs)
- source : источник для монтирования
- target : путь, по которому том монтируется в контейнере
- read_only: Установить только для чтения
- распространение : дополнительные параметры для привязки
- nocopy: дополнительная опция для тома, указывающая, запрещать ли копирование данных из контейнера при создании тома
- size : дополнительная опция для tmpfs, указывающая размер монтирования в байтах
1.20 Укажите продолжительность и значение байта
Поддерживаемые единицы длительности: США, мс, с, м, ч
Поддерживаемые единицы размера байта: b, k, m, g или b, kb, mb, gb
2. Volume configuration
В следующем примере показаны две службы: каталог данных базы данных используется совместно с другой службой в виде тома, чтобы он мог периодически выполнять резервное копирование данных:
Верхние тома могут быть пустыми, и в этот момент они настраиваются с помощью механизма Docker, который предоставляется по умолчанию (от mostct к локальному). Вы также можете указать следующий ключ
3. Пример
4. Справочная документация
docs.docker.com/compose/hotair…