Letysite.ru

IT Новости с интернет пространства
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Docker сборка контейнера

Создание Docker контейнера с вашей моделью машинного обучения

Хотя я не обладаю большим опытом в разработке программного обеспечения — я специалист по обработке данных — но, конечно, много слышала о контейнерах. Насколько легкие они в сравнении с традиционными виртуальными машинами и как они хороши в обеспечении постоянной безопасной среды для кода.

Однако, когда я попыталась создать Docker с моей собственной моделью, я быстро обнаружила, что его работа интуитивно не так понятна. Использовать Docker совсем не так же просто, как ввести RUN в начале скрипта загрузки EC2. Непредсказуемое поведение возникает часто, и довольно утомительно учиться налаживать новый инструмент.

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

Дисклеймер: модель, о которой пойдет речь — это единичная работа для конкретного случая, это НЕ веб-сервис с конечными точками API, НЕ распределенные параллельные задания. Если вы будете следовать этому руководству, весь процесс помещения кода в контейнер займет не более 25 минут.

Обязательные требования

  • AWS аккаунт
  • установленный AWS CLI
  • установленный Docker с настроенным пользовательским аккаунтом
  • установленный Python 3

Создание Docker-файла ‍♀️

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

Минимальный Dockerfile для приложения Python:

В Dockerfile выше я начала с базового образа Python 3.6. С помощью команды apt-get обновила системные библиотеки и установила make и build. Затем проверила, что версии python и pip актуальны, задала рабочий каталог, скопировала requirements.txt в контейнер, и pip установил в него все библиотеки. Наконец, я скопировала все файлы с остальным кодом в контейнер, проверила, чтобы все нужные мне файлы были на месте, и запустила файл точки входа main.py .

Dockerfile должен работать, если структура каталога кода выглядит так:

Существует множество рекомендаций, как сделать docker-файл меньше и повысить его эффективность, но большинство из них выходит за рамки этого поста. Тем не менее о нескольких вещах вам стоит помнить:

Используйте Python stretch как базовый образ

Говорят, что вместо использования универсального образа Ubuntu, стоит использовать официальные базовые образы, например, Alpine Python. Но оказалось, что с ним очень сложно работать, особенно, устанавливать пакеты. Базовый образ Ubuntu ведет себя предсказуемо, но я предлагаю начать с Python 3.6 stretch, официального образа Python, основанного на Debian 9 (он же stretch). Python stretch предоставляется с установленной и обновленной средой Python и pip. Вам остается только разобраться, как его установить, если вы выбрали Ubuntu.

Устанавливайте только то, что вам нужно

Очень заманчиво просто скопировать какой-нибудь шаблонный Dockerfile , особенно, если это ваш первый Docker-проект. Но я рекомендую устанавливать только то, что вам действительно нужно, чтобы контролировать размер образа. Если вы видите целую кучу make и build , установленных другими людьми, попробуйте не включать их сразу, сначала проверьте, работает ли ваш контейнер. Меньший размер образа — это быстрое создание и развертывание. (Еще одна причина попробовать мой минимальный шаблон выше!)

Также для сохранения наименьшего размера используйте .dockerignore , который работает так же, как .gitignore , и игнорирует файлы, не влияющие на образ.

Добавьте requirements.txt перед копированием кода

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

Если вам интересно узнать больше о Dockerfile , в Приложении есть короткий справочник по нескольким базовым командам. Переходим к Шагу 2 — создаем контейнер с только что созданным Dockerfile .

Создаем образ с Dockerfile

Команда docker build создает образ согласно инструкциям, заданным в Dockerfile . Осталось дать образу имя.

Убедитесь, что образ существует локально:

Также можно поставить tag с более понятным именем, вместо использования hash ID.

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

Поздравляю! Вы упаковали модель в контейнер, который может быть запущен в любом месте, где установлен Docker.

Основные инструкции Docker

  • Переводы, 11 марта 2019 в 0:37
  • Сергей Ринг

Это третья часть серии статей про Docker и она всецело посвящена Docker-файлам. В первой части основные концепции Docker объясняются на простых примерах из жизни. Во второй статье — краткий обзор экосистемы Docker.

Docker-образы

Docker-образ создаётся во время сборки, а Docker-контейнер — во время запуска приложения.

Docker-файл — сердце Docker’а. Он указывает Docker’у как построить образ, который будет использоваться при создании контейнера.

Каждый Docker-образ содержит файл с именем Dockerfile (он без расширения). При вызове docker build предполагается, что Dockerfile будет находиться в текущей рабочей директории. Но с помощью флага -f можно указать другое расположение.

«ООО «СТМ»», Санкт-Петербург

Контейнер состоит из ряда слоёв. Все слои доступны только для чтения, кроме последнего – он располагается над остальными. Docker-файл указывает порядок добавления слоёв.

Каждый слой — это просто файл с изменением предыдущего слоя. В Unix практически всё является файлом.
Базовый слой, его ещё называют родительским, – это начальный слой.

При загрузке Docker-образа из удалённого репозитория скачиваются только отсутствующие у вас слои. Docker экономит место и время, повторно используя уже существующие слои.

Инструкция Docker-файла — слово в верхнем регистре, которое стоит перед аргументом какой-либо команды. Каждая строка в Docker-файле может содержать инструкцию, все они обрабатываются сверху вниз. Инструкции выглядят так:

И только инструкции FROM , RUN , COPY и ADD создают слои в конечном образе. Другие инструкции производят настройку, добавляют метаданные или же просто говорят Docker’у сделать что-либо во время запуска (например открыть порт или выполнить команду).

Эта статья предполагает использование Unix Docker-образа. Вы, конечно, можете использовать и Windows Docker-образ, но он медленнее, менее удобный и, вообще, его не часто применяют. Так что, пользуйтесь Unix по возможности.

Несколько Docker-инструкций

  • FROM — задаёт родительский (главный) образ;
  • LABEL — добавляет метаданные для образа. Хорошее место для размещения информации об авторе;
  • ENV — создаёт переменную окружения;
  • RUN — запускает команды, создаёт слой образа. Используется для установки пакетов и библиотек внутри контейнера;
  • COPY — копирует файлы и директории в контейнер;
  • ADD — делает всё то же, что и инструкция COPY . Но ещё может распаковывать локальные .tar файлы;
  • CMD — указывает команду и аргументы для выполнения внутри контейнера. Параметры могут быть переопределены. Использоваться может только одна инструкция CMD ;
  • WORKDIR — устанавливает рабочую директорию для инструкции CMD и ENTRYPOINT ;
  • ARG — определяет переменную для передачи Docker’у во время сборки;
  • ENTRYPOINT — предоставляет команды и аргументы для выполняющегося контейнера. Суть его несколько отличается от CMD , о чём мы поговорим ниже;
  • EXPOSE — открывает порт;
  • VOLUME — создаёт точку подключения директории для добавления и хранения постоянных данных.

Инструкции и примеры к ним

Docker-файл чисто теоретически может содержать только одну строчку:

Docker-файл должен начинаться с инструкции FROM или ARG , за которой следует FROM . Команда FROM говорит Docker’у использовать базовый образ, который соответствует репозиторию и тегу.

В этом примере хранилище образов — Ubuntu. Ubuntu — название официального Docker-репозитория, в котором и содержится данная ОС.

Заметьте, что этот Docker-файл содержит тег для базового образа: 18.04, который указывает Docker’у, какую именно версию образа нужно использовать. Если тег не указан, по умолчанию берётся последняя версия образа. Но лучше всё же указывать тег базового образа. Когда Docker-файл, приведённый выше, используется для создания локального Docker-образа впервые, он загружает слои, указанные в образе Ubuntu.

При создании Docker-контейнера, вы помещаете наверх слой, который впоследствии можно будет изменить.

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

Подробнее про Docker-файл

Кроме того, что ваш однострочный образ сжат, он ещё и медленный, предоставляет мало информации и ничего не делает во время запуска контейнера. Посмотрите на более длинный Docker-файл, который запускает более легковесный образ, а также выполняет скрипт во время запуска.

Но что же это всё обозначает?

В роли базового образа выступает официальный Python-образ с тегом 3.7.2-alpine3.8. Как вы можете увидеть из исходников, образ включает в себя Linux, Python и ничего более. Alpine-образы очень популярны, потому что они маленькие, быстрые и безопасные. Однако Alpine-образы не поставляются сразу со всеми компонентами, характерными для вашей ОС. Некоторые пакеты вам придётся установить самостоятельно.

LABEL

Следующая инструкция — LABEL . LABEL добавляет метаданные к образу, предоставляет контактную информацию. Она не замедляет процесс запуска и не занимает много места, наоборот, обеспечивает образ полезной информацией, так что обязательно используйте её. Больше про LABEL читайте здесь.

ENV создаёт переменную окружения, которая становится доступной во время запуска контейнера. В примере выше вы могли видеть использование переменной ADMIN при создании контейнера.

ENV удобна для обозначения констант. Если константа используется в нескольких местах файла Dockerfile, и вам понадобится изменить её значение позднее, это можно будет сделать в одном месте.

Docker-файл зачастую предоставляет несколько путей решения одной задачи. Будет хорошо, если в вашем решении будет учитываться баланс Docker-соглашений, прозрачность и скорость. К примеру, RUN , CMD и ENTRYPOINT служат различным целям и могут использоваться для выполнения команд.

RUN создаёт слой во время запуска. Docker фиксирует состояние образа после каждой инструкции RUN .

Чаще всего используется для установки нужных пакетов внутрь контейнера. В примере выше RUN apk update && apk upgrade говорит Docker’у обновить пакеты из базового образа. && apk add bash указывает на то, что для базового образа нужно установить bash .

apk — это сокращение от Alpine Linux package manager. Если вы используете базовый образ не Alpine Linux, то установка пакетов производится командой RUN apt-get .

RUN и её родственные инструкции: CMD , ENTRYPOINT — могут быть как форме оболочки, так и в форме shell-скрипта. Во втором случае используют JSON-синтаксис: RUN [«my_executable», «my_first_param1», «my_second_param2»] . А в примере выше использовалась форма оболочки: RUN apk update && apk upgrade && apk add bash .

Позднее в вашем Docker-файле вы будете создавать новую директорию, используя [«mkdir», «/a_directory»] . Не забывайте, что в JSON нужно использовать двойные кавычки!

Инструкция COPY . ./app говорит Docker’у, что нужно скопировать файлы и папки из вашей локальной сборки в рабочую директорию образа. COPY создаст все нужные папки, если они отсутствуют.

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

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

Ещё официальная документация для ясности рекомендует использовать, когда это возможно, COPY вместе ADD . Жаль только, что в Docker’е невозможно использовать ADD и COPY в одной команде.

Заметьте, инструкция содержит символ . Это нужно для лучшей читаемости – так вы разбиваете длинную инструкцию на несколько строк.

CMD — инструкция для запуска чего-либо во время запуска самого контейнера. По ходу сборки она не фиксирует никакого результата. В примере выше во время сборки запускался скрипт my_script.py .

Ещё пара моментов о CMD :

  • Только одна CMD -инструкция на весь Docker-файл. Иначе все кроме последней будут проигнорированы;
  • CMD может включать исполняемый файл;
  • Если же CMD не содержит никакого файла, обязательно должна быть инструкция ENTRYPOINT . В этом случает обе инструкции должны быть в формате JSON;
  • Аргументы командной строки для запуска Docker переопределяют аргументы, предоставленные CMD в Docker-файле.

Готовы к большему?

В следующем примере представлены ещё несколько Docker-инструкций:

В Docker-файле вы можете добавлять комментарии. Комментарии начинаются со знака # .

Обычно установка пакетов — приоритетная задача для Docker’а. Как говорилось ранее, есть несколько способов загрузки пакетов при помощи инструкции RUN .

Для Alpine Docker-образа вы используете apk. apk для типичной Linux-сборки — apt-get . Например, пакеты для базового Ubuntu-образа могут быть установлены и обновлены так: RUN apt-get update && apt-get install my_package .

В дополнение к apk и apt-get , Python-пакеты могут быть установлены через pip, wheel и conda. Методы варьируются в зависимости от языка.

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

Можно использовать RUN вместе с pip и списком нужных пакетов. Для этого объедините команды установки пакетов в одну инструкцию и разделите их символом продолжения строки ( ). Этот метод позволяет улучшить читаемость и уменьшить количество слоев (из-за отсутствия возможности использовать несколько RUN инструкций).

Также вы можете запустить установщик, указав ему файл, содержащий все зависимости для вашего образа. Обычно он называется requirements.txt.

WORKDIR

Меняет текущую рабочую директорию в контейнере для инструкций: COPY , ADD , RUN и ENTRYPOINT .

  • Предпочтительно задать абсолютный путь с помощью WORKDIR, а не перемещаться по файловой системе с помощью команд cd в Docker-файле;
  • WORKDIR автоматически создаёт директорию, если её ещё нет;
  • Можно использовать несколько WORKDIR -инструкций. Если используются относительные пути — каждая инструкция поменяет рабочую директорию.

Определяет переменную для передачи из командной строки в образ. Для ARG можно указать значение по умолчанию: ARG my_var=my_default_value .

В отличие от ENV -переменных, ARG -переменные не доступны для запущенных контейнеров. Однако вы можете использовать их для установки дефолтных значений для ENV -переменных, когда вы создаёте образ. И затем ENV-переменные сохраняются. Больше про это вы найдёте здесь.

ENTRYPOINT

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

Вместо этого аргументы командной строки, передаваемые docker run myimagename , добавляются к аргументам инструкции ENTRYPOINT . Например, docker run my_image bash добавляет аргумент bash в конец, ко всем другим аргументам ENTRYPOINT .

Docker-файл обязательно должен содержать либо CMD -инструкцию, либо ENTRYPOINT -инструкцию.
В официальной документации есть несколько советов, которые помогут сделать выбор между CMD и ENTRYPOINT для начальной команды:

  • Если вам нужно запускать одну и туже команду несколько раз, выбирайте ENTRYPOINT ;
  • Используйте ENTRYPOINT , когда ваш контейнер выступает в роли исполняющейся программы;
  • При наличии дополнительных дефолтных аргументов, которые могут быть изменены через командную строку, лучше подойдёт CMD .

В примере выше, ENTRYPOINT [«python», «my_script.py», «my_var»] запускает в контейнере Python-скрипт my_script.py с аргументом my_var . Затем переменная my_var может быть использована в my_script argparse. Заметьте, у my_var есть дефолтное значение, ранее установленное в Docker-файле при помощи ARG . Так что, если аргумент не будет задан через командную строку, возьмётся его значение по умолчанию.

Как правило, Docker рекомендует вам использовать исполняемую форму с JSON-синтаксисом ENTRYPOINT [«executable», «param1», «param2»] .

EXPOSE

Инструкция EXPOSE показывает, какой порт пробрасывать из контейнера.

Используйте команду docker run с флагом -p для пробрасывания и сопоставления нескольких портов во время запуска. Флаг в верхнем регистре -P будет пробрасывать все открытые порты.

VOLUME

VOLUME определяет, где контейнер будет хранить постоянные данные и получать к ним доступ.

Заключение

В этой статье не были упомянуты такие инструкции, как USER , ONBUILD , STOPSIGNAL , SHELL , и HEALTHCHECK , информацию про них вы сможете найти здесь.

Docker, часть 3 – создание образов при помощи Dockerfile

В предыдущей части данного руководства мы увидели, как можно сохранить изменения в контейнере в новый образ. Такой способ подходит, если количество изменений относительно невелико – вводить все команды вручную каждый раз может быть затруднительно. Для упрощения процесса сборки можно воспользоваться Dockerfile. Это специальный скрипт, в котором содержатся команды и инструкции, которые будут в заданной последовательности выполнены для сборки нового образа Docker.
В данном руководстве мы рассмотрим создание собственного образа Docker при помощи Dockerfile. Он будет подробно разобран, чтобы в дальнейшем вы легко смогли создать свой собственный скрипт.

Обзор команд Dockerfile

Dockerfile – это скрипт, содержащий набор команд dockerfile и операционной системы (то есть команд Linux). Прежде чем создать свой dockerfile, давайте познакомимся с этими командами. Вот наиболее важные из них:
FROM — Указывает базовый образ для создания нового образа. Эта команда должна быть первой в dockerfile.
MAINTAINER — Необязательная команда, указывает имя владельца образа.
RUN — Используется для выполнения команды в ходе сборки образа.
ADD — Скопировать файл из файловой системы хоста в новый образ. Можно указать URL файла, в этом случае Docker загрузит его в заданную директорию.
ENV — Определяет переменную среды.
CMD — Команда которая будет запущена при создании нового контейнера на основе образа.
ENTRYPOINT — Задает команду по умолчанию, которая будет выполнена при запуске контейнера.
WORKDIR — рабочий каталог для выполнения команды CMD.
USER — Задает пользователя или UID для создаваемого на основе образа контейнера.
VOLUME — Монтирует директорию хоста в контейнер.
EXPOSE — Указывает какие порты будут слушаться в контейнере.

На первый взгляд команды CMD и ENTRYPOINT кажутся одинаковыми. Они выполняют команду при запуске контейнера. Но все таки между ними есть разница. Мы не будем вдаваться в тонкости, запомните только то что если вы укажете CMD то докер выполнит эту команду, используя стандартную команду ENTRYPOINT, которая является /bin/sh -c. И эту команду вы сможете переопределить при запуске контейнера Если вы укажете ENTRYPOINT то при запуске контейнера переопределить команду вы уже не сможете.

Создание Dockerfile

На данном этапе мы создадим для Dockerfile новую директорию и определим, что мы хотим сделать при помощи Dockerfile.
Создайте новую директорию и пустой файл в ней

Затем определим, какой образ требуется создать. В данном руководстве мы установим Nginx и PHP-FPM7, используя образ Ubuntu 18.04. Кроме того, нам потребуется Supervisord, чтобы запустить Nginx и PHP-FPM 7 одной командой.
Откройте Dockerfile в любом текстовом редакторе, например vim:

В начале файла добавьте строку с указанием базового образа, который мы будем использовать (Ubuntu 18.04):

Обновим программный репозиторий Ubuntu внутри Dockerfile при помощи команды ‘RUN‘.

Теперь установим приложения, который требуются для нашего образа. При помощи apt можно установить Nginx, PHP-FPM и Supervisord из репозитория Ubuntu. Добавьте соответствующую команду RUN:

После установки приложений их нужно настроить. Мы настроим Nginx для работы с PHP путем изменения конфигурации виртуального хоста по умолчанию. Можно отредактировать существующий файл конфигурации командой sed или заменить его новым файлом при помощи команды Dockerfile COPY.

Теперь настроим Supervisord для Nginx and PHP-FPM, точно так же заменив файл конфигурации по умолчанию новым файлом, используя команду COPY.

Создадим новую директорию для sock-файла php-fpm и изменим владельца директории /var/www/html и директории PHP на www-data.

Определим том, чтобы смонтировать указанные ниже директории на хост:

Наконец, нужно установить команду по умолчанию при запуске контейнера и открыть порты для HTTP и HTTPS. Для заданной ‘CMD’ команды по умолчанию мы создадим новый файл

start.sh, содержащий команду «supervisord», и скопируем его в новый образ командой ‘COPY‘.

Указываем порты для nginx

Сохраните и закройте файл.

Вот весь скрипт Dockerfile целиком:

Теперь внутри директории с Dockerfile создайте новый файл конфигурации виртуального хоста под названием «default», файл конфигурации supervisord «supervisord.conf» и скрипт конфигурации сервисов «start.sh».

Вставьте в файл конфигурации виртуального хоста следующий код:

Откройте файл конфигурации Supervisord:

Вставьте следующий код конфигурации:

Откройте файл start.sh.

Вставьте следующие параметры конфигурации:

Сохраните и закройте файл.

При помощи команды chmod сделайте файл start.sh исполняемым:

Создание нового образа и контейнера

Теперь, когда у нас есть все необходимые файлы конфигурации, можно собрать новый образ Docker на основе Ubuntu 18.04, используя наш Dockerfile. Для этого нужно выполнить следующую команду Docker:

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

Successfully built e7e5dc3d6cd1, говорит о том что образ создан. После успешного выполнения команды можно проверить наличие нового образа при помощи команды images:

Попробуем создать на основе этого образа новый контейнер. Предварительно создадим на хосте новую директорию для данных корня документов:

Запустим новый контейнер командой run:

И командой ps проверим, запустился ли новый контейнер под названием my_container:

Разберем команду run более подробно:

—name my_container nginx_image — на основе образа «nginx_images» создаем новый контейнер с именем «my_container».
-p 80:80 — контейнер запускаетcя на 80 порте хоста.
-v /webroot:/var/www/html — содержимое директории хоста /webroot перезаписывает директорию /var/www/html в контейнере.
Новый контейнер на основе образа nginx_image должен работать без ошибок.

Тестирование работы Nginx и PHP-FPM в контейнере

Командой echo создайте в директории /webroot новый файл index.html:

Тестирование при помощи доступа к IP-адресу хоста командой curl (замените 192.168.1.5 на свой IP-адрес):
curl 192.168.1.5
curl -I 192.168.1.5

Теперь проверим, что PHP-FPM 7.2 работает – создадим в директории /webroot новый файл c phpinfo.

Откройте веб-браузер и введите IP-адрес хоста:

Если все работает правильно, вы увидите следующий результат:

Заключение

Мы успешно создали новый образ и теперь можем создавать на его основе новые контейнеры. Более подробную информацию о создании образов и Dockerfile можно получить в документации Docker.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

Docker сборка контейнера

  • Главная
  • Блог
  • Администрирование
  • Сборка контейнеров docker с помощью контейнеров docker

Сборка контейнеров docker с помощью контейнеров docker

Организация процесса сборки приложений, а также их упаковка в контейнера.

Каждый работающий с Docker всегда сталкивается с некими сложностями. Наиболее частая их них — организация процесса сборки приложений, а также их упаковка в контейнера.

Что такое сборочный контейнер?

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

Чтобы проще было понять, рассмотрим вот такой пример: у нас есть абстрактный проект. Для его сборки и запуска необходимо выполнить некоторые действия:

  • поставить все нужные пакеты nmp;
  • инсталлировать все клиентские зависимости посредством bower;
  • использовать grunt для сборки проекта.

Для вышеописанной задачи лучше всего подойдет npm-builder. Это сборочный конвейер, включающий в себя npm, make, nodejs, g++. чтобы выполнить все три шага выше, наберите:

Вот и все, получится собрать проект буквально с помощью 3 строк кода.

Давайте разбираться, что же мы сделали. Контейнер docker с npm-builder мы запускаем в корневой папке проекта. Потом текущая директория монтируется в /data, указывающаяся как рабочая. Это необходимо для того, чтобы в ней выполнялись все команды.

Первая команда выполняет установку всех модулей nodejs в папку node_modules. Поставятся модули, прописанные в файле package.json. Вторая строчка кода необходима для инсталляции в созданную папку bower_components всех зависимостей, которые прописаны в файле bower.json. Сборка с помощью grunt осуществляется последней строкой. Опция —rm указывается при запуске контейнера и помогает удалять его после инсталляции.

Используя проект на php, у нас получится применить сборочный контейнер komposer при установке зависимостей. Наберите:

Для чего мы все это делали?

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

2. Проектный порог вхождения. Сборочные конвейеры дают возможность не заморачиваться над установкой разного ПО на компьютере разработчика. Для начала работы просто скопируйте репозиторий проекта, поставьте docker, docker-compose и сделать docker-compose up -d. А потом с docker hub сами подтянутся все контейнеры, которые нужны для сборки и установки проекта.

3. Повторное применение сборочных этапов. Если прописать в Dockerfile саму сборку, то все этапы придется прописать заново. Частично проблему получится решить за счет инструкции ONBUILD, но тогда уровень гибкости ухудшится. Это проявится когда потребуются дополнительные шаги сборки, которые придется все равно заново прописывать. Прозрачность сборки также может пострадать. Чтобы понять ход сборки, вам нужно будет смотреть на исходный файл родительского контейнера.

4. Единообразие среды, в которой происходит исполнение. Запуск приложения не зависит от этапа его сборки. А упаковка в контейнер является лишь копированием собранной программы. Что это значит? Если одни и те же приложения исполняются в контейнерах в разных средах, то в случае поломки летит всё везде одинаково.

5. Предсказуемость сборки. Не стоит проводить запуск grunt на хостовой машине, даже в самом начале применения docker.

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

7. Применение уже имеющихся инструментов. Экосистема Docker уже включает в себя кучу инструментов вроде docker-compouse. Здесь сборочные контейнеры тоже подойдут.

Конвенции во время применения сборочных контейнеров

При использовании идеи сборочных контейнеров можно выделить несколько соглашений по применению и разработке.

  • Общим может быть «интерфейс». Для наглядности можно выделить volume / data в сборочных контейнерах. Они помогут вам смонтировать исходники программ. Кроме того, есть еще и / cache, способный помочь монтировать папки с кэшем сборочного контейнера. Это могут быть посторонние зависимости вроде bower, composer кэш, npm. Для сборочных контейнеров, применять лучше один базовый образ, выполняющий роль интерфейса.
  • Метод запуска. Контейнера можно разделить на one shot и long running. Первый вариант можно запустить только один раз. Контейнер выполнит задачу и закроется. Такой вариант подходит для инсталляции зависимостей, генерации документации к API или клонирования исходных файлов. Контейнера long running являются долгоживущими. Они способны отслеживать изменения в исходных файлах, а также пересобирать проект. Контейнера можете использовать для сборки JS-файлов, SCSS и много чего еще.
  • Сборочный контейнер является внешней зависимостью относительно приложения. Мы не применяем контейнера phpunit, ведь они подключаются через composer. Его наличие и версию определяет сама программа.
  • Названия контейнеров. В имени мы применяет суффикс -builder. Получается вот что: erlnag-builder, npm-builder.

Применение вместе с docker-compose

Контейнера выгодно использовать в среде разработчика в связке с docker-compose. Это может вам пригодится если нужно внести изменения в исходники. С docker-compose если некоторые нюансы. Применить одноразовый контейнер вы сможете только с опцией -d при выполнении docker-compose. Иначе после завершения его работы закроются и все остальные контейнера.

Вот так будет выглядеть инсталляция зависимостей с применением composer для php-приложений:

Однако, долгоиграющие контейнеры работают без проблем. Например, вот так будет выглядеть инсталляция nodejs, зависимостей bower, а также запуск grunt:

Использование совместно с make

В связке с docker make, а также сборочные контейнеры применяем для сборки релизов. Команда может также применяться в качестве замены для docker-compose. Вот так будет выглядеть makefile, использующий подход со сборочными контейнерами:

В качестве вывода

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

Шпаргалка Docker

22 October 2014

Создание образа

docker pull ОБРАЗ — загружает образ из Docker Hub (аналог GitHub для Docker)

docker build ПУТЬ | URL — создает образ с помощью Dockerfile
Параметры:

  • -t | —tag=»» — помечает созданный образ переданным названием (и, тэгом, если он будет передан)
  • —rm — Удаляет промежуточные контейнеры после успешной сборки (по умолчанию == true)
Читать еще:  Как закачать флеш плеер

Управление образами

docker rmi — Удаляет образ, образ не может быть удален, если существуют контейнеры (даже незапущенные), которые основаны
на данном образе
Параметры:

  • -f — позволяет удалить образ даже если на нём основаны контейнеры

docker images — Отображает список всех существующих образов
Параметры:

  • -a | —all — отображает все образы (по умолчанию не отображает промежуточные контейнеры)
  • -q — отображает только id образов, вместо таблицы

Запуск и остановка контейнеров

docker run ОБРАЗ [КОМАНДА + АРГУМЕНТЫ] — Запускает выбранный образ в новом контейнере
Параметры:

  • -d | —detach — запускает контейнер в фоновом режиме и выводит только id свежесозданного контейнера. (по умолчанию == false )
  • -i | —interactive — запускает контейнер в интерактивном режиме (оставляет STDIN открытым, даже если контейнер запущен в неприкрепленном режиме)
  • -t | —tty — запускает псевдотерминал, часто используется с -i
  • -p | —publish=[] — пробрасывает порты контейнера в хост. Формат: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
  • -e | —env=[] — пробрасывает переменные окружения внутрь контейнера.
  • -v | —volume=[] — пробрасывает директорию файловой системы внутрь контейнера

docker stop КОНТЕЙНЕР — останавливает контейнер, передавая внутрь SIGTERM, а по истечении таймаута — SIGKILL

  • docker start КОНТЕЙНЕР — запускает остановленный контейнер.
    Параметры:
    • -i | —interactive — аналогично docker run -i
  • docker restart КОНТЕЙНЕР — Перезапускает выбранный контейнер с помощью docker stop и docker start
  • docker kill КОНТЕЙНЕР — Убивает контейнер, передавая внутрь SIGKILL
  • Управление контейнерами

    • docker port КОНТЕЙНЕР — отображает маппинг портов между хостом и контейнером
    • docker ps — отображает список запущенных контейнеров
      Параметры:
      • -a | —all=(true|false) — отображать ли все контейнеры. По умолчанию == false , т.е. отображаются только запущенные контейнеры
      • -q — отображает только ID контейнеров вместо таблицы
    • docker rm КОНТЕЙНЕР — удаляет контейнер. По умолчанию можно удалить только запущенный контейнер.
      Параметры:
      • -f | —force=(true|false) — позволяет удалить запущенный контейнер. Используется передача SIGKILL внутрь.
    • docker diff — отображает изменения относительно образа.
    Читать еще:  Сбор статистики использования устройств сети

    Синтаксис Dockerfile

    Dockerfile служит скриптом сборки для команды docker build . Перед началом сборки docker передает сборщику всё содержимое папки с Dockerfile’ом,
    поэтому располагать его в корневой директории системы будет не лучшей идеей.

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

    FROM ОБРАЗ | FROM ОБРАЗ:ТЭГ — Задает базовый образ для последующих инструкций. Может встречаться несколько раз в одном Dockerfile,
    если необходимо собрать несколько образов за раз.

    MAINTAINER имя — Позволяет задать поле Author сгенерированного образа

    RUN команда | RUN [«исполняемый файл», «параметр1», «параметр2», ..] — Запускает команду на основе текущего образа и фиксирует изменения в новом образе. Новый образ будет использован для исполнения последующих инструкций. Первый синтаксис подразумевает запуск команд в стандартной оболочке (binsh -c)

    CMD [«исполняемый файл», «параметр1», «параметр2»] | CMD [«параметр1», «параметр2»] | CMD команда параметр1 параметр2 — Предоставляет значения по умолчанию для запуска контейнера. Эти значения могут как включать исполняемый файл (варианты 1, 3), так и не включать его (вариант 2). В последнем случае запускаемая команда
    должна быть задана с помощью инструкции ENTRYPOINT .

    EXPOSE порт — Информирует Docker, что контейнер будет прослушивать указанные порты во время исполнения. Docker может использовать эту информацию, чтобы соединять контейнеры между собой используя связи. EXPOSE сам по себе не делает порт доступным из хостовой системы. Для того, чтобы открыть порты в хостовую систему следует использовать флаг -p .

    ENV ключ значение — Позволяет задавать переменные окружения. Эти переменные будут использованы при запуске контейнера из собранного образа. Могут быть просмотрены с помощью команды docker inspect , а также переопределены с помощью флага —env команды docker run .

    ADD ОТКУДА КУДА — Используется для добавления новых файлов, директорий или ссылок на удалённые файлы в файловую систему контейнера. Несколько ОТКУДА может быть передано одновременно, но в этом случае все адреса должны быть относительны для директории, из которой происходит сборка. Каждый вхождение ОТКУДА может содержатьодин или несколько символов подстановки, которые будут разрешены с использование функции языка Go filepath.Match. КУДА должен быть абсолютным путем внутри контейнера.

    Читать еще:  Окраска сборных моделей

    ENTRYPOINT [«исполняемый файл», «параметр1», «параметр2»] | ENTRYPOINT команда параметр1 параметр2 — позволяет сконфигурировать контейнер так, чтобы он запускался как исполняемый файл. В отличии от команды CMD значение не будет переопределено аргументами, переданными в команду docker run . Таким образом, аргументы из команды docker run будут переданы внутрь контейнера, т.е. docker run ОБРАЗ -d передаст -d исполняемому файлу.

    VOLUME [ПУТЬ] — создает точку монтирования с указанным именем и помечает её как содержащую подмонтированные разделы из хостовой системы или других контейнеров. Значение может быть задано как массив JSON, например, VOLUME [«/var/log/»] , так и как обычной строкой с одним или несколькими аргументами, например VOLUME /var/log или VOLUME /var/log /var/db

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

    WORKDIR ПУТЬ — задает рабочую директорию для команд RUN , CMD и ENTRYPOINT . Инструкция может быть использована несколько раз. Если ПУТЬ относителен, то он будет относительным для ПУТИ, заданным предыдущей инструкцией WORKDIR .

    Ссылка на основную публикацию
    Adblock
    detector