Перейти к содержанию

Dockerfile

Инструкции

  • FROM имя-образа — какой образ использовать в качестве базы (должна быть первой строкой в любом Dockerfile).
  • MAINTAINER имя — имя мантейнера данного Dockerfile.
  • RUN команда — запустить указанную команду внутри контейнера.
  • CMD команда — выполнить команду при запуске контейнера (обычно идет последней).
  • EXPOSE порт — список портов, которые будет слушать контейнер (используется механизмом линковки).
  • ENV ключ значение — создать переменную окружения.
  • ADD путь путь — скопировать файл/каталог внутрь контейнера/образа (первый аргумент может быть URL).
  • ENTRYPOINT команда — команда для запуска приложения в контейнере (по умолчанию /bin/sh -c).
  • VOLUME путь — пробросить в контейнер указанный каталог (аналог опции -v).
  • USER имя — сменить юзера внутри контейнера.
  • WORKDIR путь — сменить каталог внутри контейнера.
  • ONBUILD \[ИНСТРУКЦИЯ\] — запустить указанную инструкцию Dockerfile только в том случае, если образ используется для сборки другого образа (с помощью FROM).

Формат Dockerfile:

# Comment
INSTRUCTION arguments

Инструкция не чувствительна к регистру. Тем не менее, рекомендуется использовать ВЕРХНИЙ РЕГИСТР что бы было проще отличить инструкцию от ее аргументов.

Docker выполняет инструкции из Dockerfile по порядку. Первой инструкцией должна быть FROM что бы задать базовый образ на основе которого будет происходить сборка.

Файл .dockerignore

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

Интерфейс командной строки интерпретирует .dockerignore файл как список паттернов. Для целей сопоставления, корень контекста считается как рабочий и корневой каталог. К примеру, паттерны /foo/bar и foo/bar исключают файл или каталог с именем bar в подкаталоге foo контекста или корне репозитория git расположенного по заданному URL.

Если строка в файле .dockerignore начинается с #, то строка считается комментарием.

Вот пример .dockerignore файла:

# comment
    */temp*
    */*/temp*
    temp?

Почему, собирая образ с помощью Dockerfile, я получаю толстый слоеный пирог?

Команда docker build собирает образ из инструкций Dockerfile не атомарно, а выполняя каждую команду по отдельности. Работает это так: сначала Docker читает команду FROM и берет указанный в ней образ за основу, затем читает следующую команду, запускает контейнер из образа, выполняет команду и делает commit, получая новый образ, затем читает следующую команду и делает то же самое по отношению к сохраненному в предыдущем шаге образу. Другими словами, каждая команда Dockerfile добавляет новый слой к существующему образу, поэтому стоит избегать длинных списков команд вроде таких:

RUN apt-get update
RUN apt-get upgrade
RUN apt-get install nginx

А вместо этого писать все одной строкой:

RUN apt-get update &&\
      apt-get upgrade &&\
      apt-get install nginx

Ну и в целом не особо увлекаться составлением длинных Dockerfile. Кстати, в Docker есть лимит на количество слоев, и он равен 127. Это искусственное ограничение, введенное с целью не допустить деградации производительности при большом количестве слоев и не позволить админам использовать саму идею слоев не по назначению.