Поиск…


Вступление

Dockerfiles - это файлы, используемые для программной сборки изображений Docker. Они позволяют быстро и воспроизводить изображение Docker, и поэтому они полезны для совместной работы. Dockerfiles содержит инструкции по созданию изображения Docker. Каждая команда записывается в одну строку и указывается в форме <INSTRUCTION><argument(s)> . Dockerfiles используется для построения Docker изображений с помощью docker build команды.

замечания

Докер-файлы имеют форму:

# This is a comment
INSTRUCTION arguments
  • Комментарии начинаются с #
  • Инструкции только в верхнем регистре
  • Первая инструкция файла Docker должна быть FROM чтобы указать базовое изображение

При создании файла Docker клиент Docker отправляет «сценарий сборки» демону Docker. Контекст сборки включает все файлы и папку в том же каталоге, что и файл Docker. Операции COPY и ADD могут использовать только файлы из этого контекста.


Некоторые файлы Docker могут начинаться с:

# escape=`

Это используется для указания парсеру Docker использовать ` как escape-символ вместо \ . Это в основном полезно для файлов Windows Docker.

HelloWorld Dockerfile

Минимальный файл Dockerfile выглядит так:

FROM alpine
CMD ["echo", "Hello StackOverflow!"]

Это даст указание Docker создать изображение на основе Alpine ( FROM ), минимальное распределение для контейнеров и запустить определенную команду ( CMD ) при выполнении полученного изображения.

Создайте и запустите:

docker build -t hello .
docker run --rm hello

Это приведет к выводу:

Hello StackOverflow!

Копирование файлов

Чтобы скопировать файлы из контекста сборки в образ Docker, используйте инструкцию COPY :

COPY localfile.txt containerfile.txt

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

COPY ["local file", "container file"]

Команда COPY поддерживает подстановочные знаки. Его можно использовать, например, для копирования всех изображений в каталог images/ :

COPY *.jpg images/

Примечание: в этом примере images/ могут отсутствовать. В этом случае Docker создаст его автоматически.

Показ порта

Чтобы объявить открытые порты из файла Dockerfile, используйте инструкцию EXPOSE :

EXPOSE 8080 8082

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

Лучшие докеры

Групповые общие операции

Docker создает изображения как набор слоев. Каждый уровень может добавлять только данные, даже если эти данные говорят о том, что файл был удален. Каждая инструкция создает новый слой. Например:

RUN apt-get -qq update
RUN apt-get -qq install some-package

Имеет пару недостатков:

  • Он создаст два слоя, создавая более крупное изображение.
  • Использование apt-get update только в заявлении RUN вызывает проблемы с кешированием, и впоследствии инструкции apt-get install могут завершиться неудачно . Предположим, что вы позже модифицируете apt-get install путем добавления дополнительных пакетов, затем докер интерпретирует начальные и измененные инструкции как идентичные и повторно использует кеш из предыдущих шагов. В результате команда apt-get update не выполняется, поскольку ее кешированная версия используется во время сборки.

Вместо этого используйте:

RUN apt-get -qq update && \
    apt-get -qq install some-package

так как это создает только один слой.

Упомяните сопровождающего

Обычно это вторая строка файла Docker. Он рассказывает, кто несет ответственность и сможет помочь.

LABEL maintainer John Doe <[email protected]>

Если вы пропустите его, он не сломает ваше изображение. Но это тоже не поможет вашим пользователям.

Будьте краткими

Держите файл Dockerfile коротким. Если необходима сложная настройка, попробуйте использовать выделенный сценарий или настроить базовые изображения.

Инструкция пользователя

USER daemon

Инструкция USER устанавливает имя пользователя или UID для использования при запуске изображения и любых инструкций RUN , CMD и ENTRYPOINT которые следуют за ним в Dockerfile .

Инструкция WORKDIR

WORKDIR /path/to/workdir

Инструкция WORKDIR устанавливает рабочий каталог для любых инструкций RUN , CMD , ENTRYPOINT , COPY и ADD которые следуют за ним в файле Docker. Если WORKDIR не существует, он будет создан, даже если он не используется в любой последующей инструкции Dockerfile .

Его можно использовать несколько раз в одном Dockerfile . Если предоставлен относительный путь, он будет относиться к пути предыдущей инструкции WORKDIR . Например:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

Результатом окончательной команды pwd в этом Dockerfile будет /a/b/c .

Инструкция WORKDIR может разрешать переменные среды, предварительно установленные с помощью ENV . Вы можете использовать только переменные среды, явно установленные в Dockerfile . Например:

ENV DIRPATH /path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

Результатом окончательной команды pwd в этом файле Docker будет /path/$DIRNAME

Инструкция 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

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

Примечание. Если какие-либо шаги сборки изменяют данные в томе после того, как они были объявлены, эти изменения будут отброшены.

Примечание. Список анализируется как массив JSON, что означает, что вы должны использовать двойные кавычки (") вокруг слов, а не одиночных кавычек (').

Инструкция COPY

COPY имеет две формы:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"] (this form is required for paths containing whitespace)

Инструкция COPY копирует новые файлы или каталоги из <src> и добавляет их в файловую систему контейнера по пути <dest> .

Можно указать несколько ресурсов <src> но они должны относиться к исходному каталогу, который строится (контекст сборки).

Каждый <src> может содержать подстановочные знаки, и сопоставление будет выполняться с помощью правил Go's filepath.Match . Например:

COPY hom* /mydir/        # adds all files starting with "hom"
COPY hom?.txt /mydir/    # ? is replaced with any single character, e.g., "home.txt"

<dest> - это абсолютный путь или путь относительно WORKDIR , в который будет скопирован источник в контейнере назначения.

COPY test relativeDir/   # adds "test" to `WORKDIR`/relativeDir/
COPY test /absoluteDir/  # adds "test" to /absoluteDir/

Все новые файлы и каталоги создаются с UID и GID из 0.

Примечание. Если вы создаете с помощью stdin ( docker build - < somefile ), контекст сборки не существует, поэтому COPY нельзя использовать.

COPY подчиняется следующим правилам:

  • Путь <src> должен находиться внутри контекста сборки; вы не можете COPY ../something / something, потому что первым шагом сборки docker является отправка каталога контекста (и подкаталогов) демона докеров.

  • Если <src> является каталогом, копируется все содержимое каталога, включая метаданные файловой системы. Примечание. Сама директория не копируется, а только ее содержимое.

  • Если <src> - это любой другой тип файла, он копируется отдельно вместе с его метаданными. В этом случае, если <dest> заканчивается конечной косой чертой /, он будет считаться каталогом, а содержимое <src> будет записано в <dest>/base(<src>) .

  • Если указано несколько ресурсов <src> , либо напрямую, либо из-за использования подстановочного знака, то <dest> должен быть каталогом, и он должен заканчиваться косой чертой / .

  • Если <dest> не заканчивается конечной косой чертой, он будет считаться обычным файлом, а содержимое <src> будет записано в <dest> .

  • Если <dest> не существует, он создается вместе со всеми отсутствующими каталогами на своем пути.

Инструкция ENV и ARG

ENV

ENV <key> <value>
ENV <key>=<value> ...

Команда ENV устанавливает переменную среды <key> в значение. Это значение будет находиться в среде всех команд «потомки» Dockerfile и также может быть заменено inline во многих.

Инструкция 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 run --env <key>=<value> и изменить их с помощью docker run --env <key>=<value> .

ARG

Если вы не хотите настаивать на настройке, вместо этого используйте ARG . ARG будет устанавливать среды только во время сборки. Например, установка

ENV DEBIAN_FRONTEND noninteractive

могут запутать пользователей apt-get на образ Debian, когда они вводят контейнер в интерактивном контексте через docker exec -it the-container bash .

Вместо этого используйте:

ARG DEBIAN_FRONTEND noninteractive

Вы можете альтернативно также установить значение для одной команды только с помощью:

RUN <key>=<value> <command>

ЭКСПОЗИЦИЯ

EXPOSE <port> [<port>...]

Команда EXPOSE информирует Docker о том, что контейнер прослушивает указанные сетевые порты во время выполнения. EXPOSE НЕ делает порты контейнера доступными для хоста. Для этого вы должны использовать флаг -p для публикации диапазона портов или флага -P для публикации всех открытых портов. Эти флаги используются в docker run [OPTIONS] IMAGE [COMMAND][ARG...] чтобы открыть порт для хоста. Вы можете открыть один номер порта и опубликовать его извне под другим номером.

docker run -p 2500:80 <image name>

Эта команда создаст контейнер с именем <image> и привяжет порт контейнера 80 к порту 2500 хост-машины.

Чтобы настроить перенаправление портов в главной системе, см. Использование флага -P . Сетевая функция Docker поддерживает создание сетей без необходимости раскрывать порты в сети, подробную информацию см. В обзоре этой функции).

Инструкция 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 s в изображениях FROM . Если Docker обнаруживает метку / ключ, который уже существует, новое значение переопределяет любые предыдущие метки с идентичными ключами.

Чтобы просмотреть метки изображений, используйте команду проверки докеров.

"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"
},

Инструкция CMD

Инструкция CMD имеет три формы:

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)

В Dockerfile может быть только одна команда CMD . Если вы перечислите несколько CMD тогда вступит в силу только последний CMD .

Основной целью CMD является предоставление значений по умолчанию для исполняющего контейнера. Эти значения по умолчанию могут включать исполняемый файл, или они могут опустить исполняемый файл, и в этом случае вы должны указать инструкцию ENTRYPOINT .

Примечание. Если CMD используется для предоставления аргументов по умолчанию для инструкции ENTRYPOINT инструкции CMD и ENTRYPOINT следует указывать в формате массива JSON.

Примечание. Форма exec анализируется как массив JSON, что означает, что вы должны использовать двойные кавычки («) вокруг слов, а не одиночных кавычек (').

Примечание. В отличие от формы оболочки форма exec не вызывает командную оболочку. Это означает, что нормальной обработки оболочки не происходит. Например, CMD [ "echo", "$HOME" ] не будет делать замену переменных в $HOME . Если вы хотите обработать оболочку, то либо используйте форму оболочки, либо выполните оболочку напрямую, например: CMD [ "sh", "-c", "echo $HOME" ] .

При использовании в форматах оболочки или exec команда CMD устанавливает команду, которая должна выполняться при запуске изображения.

Если вы используете форму оболочки CMD , тогда команда будет выполняться в /bin/sh -c :

FROM ubuntu
CMD echo "This is a test." | wc -

Если вы хотите запустить команду без оболочки, вы должны выразить команду как массив JSON и предоставить полный путь к исполняемому файлу. Эта форма массива является предпочтительным форматом CMD . Любые дополнительные параметры должны быть индивидуально выражены как строки в массиве:

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

Если вы хотите, чтобы ваш контейнер запускал один и тот же исполняемый файл каждый раз, вам следует рассмотреть возможность использования ENTRYPOINT в сочетании с CMD . См. ENTRYPOINT .

Если пользователь указывает аргументы для запуска docker, они будут переопределять значение по умолчанию, указанное в CMD .

Примечание: не путайте RUN с CMD . RUN фактически выполняет команду во время построения изображения и фиксирует результат; CMD ничего не выполняет во время сборки, но указывает намеченную команду для изображения.

Инструкция MAINTAINER

MAINTAINER <name>

Инструкция MAINTAINER позволяет вам установить поле Author созданных изображений.

НЕ ИСПОЛЬЗУЙТЕ ДИРЕКТИВУ ГЛАВНОГО ОБОРУДОВАНИЯ

Согласно официальной документации Docker, инструкция MAINTAINER устарела. Вместо этого следует использовать инструкцию LABEL для определения автора созданных изображений. Команда LABEL более гибкая, позволяет устанавливать метаданные и может быть легко просмотрена с помощью docker inspect команды.

LABEL maintainer="[email protected]"

ОТ Инструкция

FROM <image>

Или же

FROM <image>:<tag>

Или же

FROM <image>@<digest>

Инструкция FROM устанавливает базовое изображение для последующих инструкций. Таким образом, действительный файл Dockerfile должен иметь FROM качестве первой инструкции. Изображение может быть любым допустимым изображением - его особенно легко начать, потянув изображение из публичных репозиториев.

FROM должна быть первой командой без комментария в файле Docker.

FROM может появляться несколько раз в пределах одного файла Docker для создания нескольких изображений. Просто запишите последний вывод ID изображения с помощью фиксации перед каждой новой командой FROM .

Значения тегов или дайджеста являются необязательными. Если вы опустите любой из них, строитель принимает по умолчанию последний. Строитель возвращает ошибку, если она не может соответствовать значению тега.

Инструкция RUN

RUN имеет 2 формы:

RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] (exec form)

Команда RUN будет выполнять любые команды в новом слое поверх текущего изображения и фиксировать результаты. Результирующее зафиксированное изображение будет использоваться для следующего шага в Dockerfile .

Инструкции Layout 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" ] .

Примечание. В форме JSON необходимо избегать обратных косых черт. Это особенно актуально для Windows, где обратная косая черта - разделитель путей. Следующая строка в противном случае была бы обработана как форма оболочки из-за недействительности JSON и непредвиденного сбоя: RUN ["c:\windows\system32\tasklist.exe"]

Правильный синтаксис для этого примера: RUN ["c:\\windows\\system32\\tasklist.exe"]

Кэш для команд RUN автоматически не отменяется во время следующей сборки. Кэш для команды, такой как RUN apt-get dist-upgrade -y будет использоваться повторно во время следующей сборки. Кэш для команд RUN может быть недействительным с использованием флага -no-cache, например docker build --no-cache.

Дополнительную информацию см. В Руководстве по лучшей практике Dockerfile.

Кэш для команд RUN может быть аннулирован инструкциями ADD . Подробнее см. Ниже.

Инструкция ONBUILD

ONBUILD [INSTRUCTION]

Инструкция ONBUILD добавляет к изображению триггерную инструкцию, которая будет выполнена позднее, когда изображение используется в качестве основы для другой сборки. Триггер будет выполняться в контексте нисходящей сборки, как если бы он был вставлен сразу после инструкции FROM в нисходящем файле Docker.

Любая инструкция сборки может быть зарегистрирована как триггер.

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

Например, если ваш образ является многоразовым конструктором приложений Python, для его использования в конкретном каталоге потребуется исходный код приложения, и после этого может потребоваться вызывать скрипт сборки. Вы не можете просто вызывать ADD и RUN сейчас, потому что у вас еще нет доступа к исходному коду приложения, и для каждой сборки приложения он будет отличаться. Вы можете просто предоставить разработчикам приложений шаблонный файл Docker для копирования-вставки в свое приложение, но это неэффективно, подвержено ошибкам и сложно обновить, поскольку оно смешивается с кодом приложения.

Решение состоит в том, чтобы использовать ONBUILD для регистрации предварительных инструкций для запуска позже, на следующем этапе сборки.

Вот как это работает:

Когда он встречает инструкцию ONBUILD , строитель добавляет триггер к метаданным создаваемого образа. Эта инструкция не влияет на текущую сборку.

В конце сборки список всех триггеров хранится в манифесте изображения под ключ OnBuild. Их можно проверить с помощью команды docker inspect . Позже изображение может быть использовано в качестве основы для новой сборки, используя инструкцию FROM . В процессе обработки команды FROM строитель нисходящего потока ищет триггеры ONBUILD и выполняет их в том же порядке, в котором они были зарегистрированы. Если какой-либо из триггеров терпит неудачу, команда FROM прерывается, что, в свою очередь, приводит к сбою сборки. Если все триггеры преуспевают, команда FROM завершается, и сборка продолжается, как обычно.

После запуска триггеры очищаются от окончательного изображения. Другими словами, они не унаследованы сборниками «grand-children».

Например, вы можете добавить что-то вроде этого:

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

Предупреждение: ONBUILD использование ONBUILD ONBUILD с использованием ONBUILD ONBUILD запрещен.

Предупреждение: инструкция ONBUILD может не запускать инструкции FROM или MAINTAINER .

Инструкция STOPSIGNAL

STOPSIGNAL signal

Инструкция STOPSIGNAL устанавливает сигнал системного вызова, который будет отправлен в контейнер для выхода. Этот сигнал может быть допустимым числом без знака, которое соответствует позиции в таблице syscall ядра, например 9, или имени сигнала в формате SIGNAME, например SIGKILL.

Инструкция HEALTHCHECK

Инструкция HEALTHCHECK имеет две формы:

HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any healthcheck inherited from the base image)

Команда HEALTHCHECK сообщает Docker, как тестировать контейнер, чтобы проверить, что он все еще работает. Это может обнаружить такие случаи, как веб-сервер, который застрял в бесконечном цикле и не может обрабатывать новые соединения, даже несмотря на то, что процесс сервера все еще работает.

Когда в контейнере указан медицинский осмотр, у него есть состояние здоровья в дополнение к его нормальному состоянию. Первоначально этот статус запускается. Всякий раз, когда проходит проверка здоровья, он становится здоровым (независимо от того, в каком состоянии он был ранее). После определенного количества последовательных сбоев он становится нездоровым.

Параметры, которые могут отображаться перед CMD :

--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--retries=N (default: 3)

Сначала проверка работоспособности начнется через несколько секунд после запуска контейнера, а затем снова через несколько секунд после завершения каждой предыдущей проверки.

Если один прогон проверки занимает больше времени, чем тайм-аут, то проверка считается неудачной.

Это требует повторных попыток проверки работоспособности контейнера, который считается нездоровым.

В HEALTHCHECK может быть только одна инструкция Dockerfile . Если вы перечислите более одного, тогда HEALTHCHECK силу только последний HEALTHCHECK .

Команда после ключевого слова CMD может быть либо командой оболочки (например, HEALTHCHECK CMD /bin/check-running ), либо массивом exec (как и в других командах Dockerfile, см., Например, ENTRYPOINT для деталей).

Статус выхода команды указывает состояние работоспособности контейнера. Возможные значения:

  • 0: success - контейнер здоров и готов к использованию
  • 1: unhealthy - контейнер работает неправильно
  • 2: starting - контейнер еще не готов к использованию, но работает правильно

Если зонд возвращает 2 («запуск»), когда контейнер уже вышел из состояния «запуска», тогда он рассматривается как «нездоровый».

Например, чтобы проверить каждые пять минут или так, чтобы веб-сервер мог обслуживать главную страницу сайта в течение трех секунд:

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 должна быть записана в форме JSON в файле Docker.

Инструкция 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 может быть затронута следующими инструкциями, когда их форма оболочки используется в файле Docker: RUN , CMD и ENTRYPOINT .

Следующий пример - это общий шаблон, найденный в Windows, который можно упростить с помощью инструкции SHELL :

...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...

Команда, вызываемая докером, будет:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

Это неэффективно по двум причинам. Во-первых, вызывается ненужный командный процессор cmd.exe (aka shell). Во-вторых, для каждой инструкции RUN в форме оболочки требуется дополнительная команда powershell-command, префиксная команда.

Чтобы сделать это более эффективным, можно использовать один из двух механизмов. Один из них - использовать форму JSON команды RUN такую ​​как:

...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...

Хотя форма JSON недвусмысленна и не использует ненужный cmd.exe, для этого требуется более многословие посредством двойного кавычки и экранирования. Альтернативным механизмом является использование инструкции SHELL и формы оболочки, что делает более естественным синтаксис для пользователей Windows, особенно в сочетании с директивой анализа парсера:

# 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 также может использоваться для изменения способа работы оболочки. Например, используя SHELL cmd /S /C /V:ON|OFF в Windows, можно было бы изменить семантику расширения переменных среды с задержкой.

Инструкция SHELL может также использоваться в Linux, если требуется чередование оболочки zsh, csh, tcsh и других.

Функция SHELL была добавлена ​​в Docker 1.12.

Установка пакетов Debian / Ubuntu

Запустите установку в команде с одним запуском, чтобы объединить обновление и установить. Если позже вы добавите больше пакетов, это снова запустит обновление и установит все необходимые пакеты. Если обновление запускается отдельно, оно будет кэшироваться и пакеты могут завершиться неудачей. Установка интерфейсов в неинтерактивный и передача -y для установки необходима для сценариев установки. Очистка и очистка в конце установки минимизирует размер слоя.

FROM debian

RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    git \
    openssh-client \
    sudo \
    vim \
    wget \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow