Статьи

От Ваадина до Докера — путешествие новичка

Я большой   фанат Vaadin, и я создал  семинар Github, который  я могу продемонстрировать на конференциях. Общая проблема с такого рода семинарами состоит в том, что участники должны заранее подготовить свои рабочие места … и всегда есть значительная их часть, которая идет не со всем готовым. На этом этапе докладчику доступны два варианта: либо подождать, пока каждый участник закончит подготовку, — слишком плохо для людей, которые нашли время дома, чтобы сделать это, либо начать в любом случае — и потерять неготовую часть. ,

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

  1. Установить Git
  2. Установите Java, Maven и Tomcat
  3. Клонировать репозиторий
  4. Построить проект (подготовить репозиторий Maven)
  5. Разверните встроенное веб-приложение
  6. Запустить Tomcat

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

Начиная с докера

Первым шагом было познакомиться с основами Docker. К счастью, у меня была возможность посетить семинар Docker Дэвида Гаге в Duchess Swiss. Это включало как установку Docker, так и основы Dockerfile. Я предполагаю, что читатели также имеют базовое понимание Docker.

Для тех, кто этого не делает, я думаю, что просмотр официальной документации Докера — хорошая идея:

Сборка моего первого Dockerfile

Образ Docker можно создать с помощью следующей команды, запущенной в каталоге файла Docker:

$ docker build -t vaadinworkshop .

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

Get http:///var/run/docker.sock/v1.14/containers/json: dial unix /var/run/docker.sock: no such file or directory

Причина в том, что никто не экспортировал необходимые переменные среды, отображаемые в информационном сообщении boot2docker. Если вы потеряли точные данные, не беспокойтесь, просто используйте параметр shellinit boot2docker:

$ boot2docker shellinit
Writing /Users/i303869/.docker/boot2docker-vm/ca.pem:
Writing /Users/i303869/.docker/boot2docker-vm/cert.pem:
Writing /Users/i303869/.docker/boot2docker-vm/key.pem:
    export DOCKER_HOST=tcp://192.168.59.103:2376
    export DOCKER_CERT_PATH=/Users/i303869/.docker/boot2docker-vm

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

Далее в строке следующая ошибка:

Get http://192.168.59.103:2376/v1.14/containers/json: malformed HTTP response "x15x03x01x00x02x02"

Это сообщение об ошибке, по-видимому, из-за несоответствия между версиями клиента и сервера. Кажется, это из-за ошибки в Mac OSX при обновлении. Для долгосрочного решения переустановите Docker с нуля; для быстрого исправления используйте флаг —tls с командой docker. Так как набрать все это довольно громоздко, можно использовать псевдоним:

$ alias docker="docker --tls"

Моя последняя ошибка при создании образа — сборка Dockerfile из не пустой директории. Docker отправляет каждый найденный файл в каталоге Dockerfile в контейнер Docker для сборки:

$ docker --tls build -t vaadinworkshop .
Sending build context to Docker daemon Too many kB

Исправление: не пытайтесь сделать это дома и начинайте с контейнера каталога только Dockerfile.

Начиная с нуля

Dockerfiles описывают изображения — изображения создаются в виде многослойного списка инструкций. Изображения Docker разработаны на основе одного наследования: для одного изображения должен быть установлен один родитель. Изображения , не требующие родителя начинается  scratch, но Докер обеспечивает 4 базовые официальные распределения:  busyboxdebianubuntu и  centos (операционные системы , как правило , начало хорошо).

Чего вы хотите добиться, необходимо выбрать правильного родителя. Учитывая требования, которые я установил для себя (Java, Maven, Tomcat и Git), я попытался найти правильное начальное изображение. Многие Docker-файлы уже доступны онлайн на  Docker-хабе . Приложение для просмотра приложений неплохое, но, если честно, поиск действительно можно улучшить.

Мое намерение состояло в том, чтобы использовать изображение, которое соответствовало большинству моих требований, затем заполнить пробел. Я не мог найти изображение, предоставляющее Git, но я думал, что  Dockerfile dgageot / maven  будет хорошей отправной точкой. Проблема заключается в том, что базовое изображение является BusyBox и не дает установки вне коробки ( apt-getyum, что угодно). По этой причине Дэвид использует много завитков, чтобы получить Java 8 и Maven в своих файлах Dockerfiles.

Я глупо подумал, что могу использовать  другой вариант busybox,  который предоставляет   установщик opkg . Через некоторое время я накопил много проблем, решая один заголовок к другому. В конце концов я решил использовать ОС, которая мне наиболее удобна, и сам все установить:

FROM ubuntu:utopic

Сценарии установки Java 

Установка пакетов git, maven и tomcat очень проста (если вы не забыли использовать неинтерактивные опции) с RUN и apt-get:

RUN apt-get update && \
    apt-get install -y --force-yes git maven tomcat8

Java не попадает в эту замечательную модель, поскольку Oracle хочет, чтобы вы приняли лицензию. Однако хорошие люди опубликовали его в стороннем репо. 

Шаги следующие: 

  1. Добавьте необходимый репозиторий пакетов 
  2. Настройте систему для автоматического принятия лицензии 
  3. Настройте систему для добавления несертифицированных пакетов 
  4. Обновить список репозиториев 
  5. Наконец, установите пакет 
  6. Также добавьте пакет для конфигурации системы Java 8.

RUN echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" | tee -a /etc/apt/sources.list && \
    echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections && \
    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886
 
RUN apt-get update && \
    apt-get install -y --force-yes oracle-java8-installer oracle-java8-set-default

Создание источников 

Получить исходные тексты семинаров и создать их довольно просто, следуя инструкциям:

RUN git clone  https://github.com/nfrankel/vaadin7-workshop.git
WORKDIR /vaadin7-workshop
RUN mvn package

Недостаток этого подхода заключается в том, что Maven будет запускаться из нового репозитория и, таким образом, загружать Интернет при первом запуске. Сначала я хотел смонтировать том с хоста в контейнер, чтобы разделить папку ~ / .m2 / repository, чтобы избежать этого, но я заметил, что это можно сделать только во время выполнения с помощью  -v опции, поскольку  VOLUME инструкция не может указывать на хост каталог.

Начало изображения

Простейшая команда для запуска созданного образа Docker следующая:

$ docker run -p 8080:8080

Не забудьте переадресацию портов из контейнера на хост, 8080 для стандартного порта HTTP. Также обратите внимание, что нет необходимости запускать контейнер как демон (с  -d опцией). Дополнительным преимуществом является то, что стандартный вывод  CMD (см. Ниже) будет перенаправлен на хост. При работе в качестве демона и желании проверить журналы, необходимо выполнить bash в контейнере, что требует последовательности громоздких манипуляций.

Настройка и запуск Tomcat

Tomcat можно запустить при запуске контейнера, просто добавив следующую инструкцию в Dockerfile:

CMD ["catalina.sh", "run"]

Однако попытка запустить контейнер на этом этапе приведет к следующей ошибке:

Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.ClassLoaderFactory validateFile
WARNING: Problem with directory [/usr/share/tomcat8/common/classes], exists: [false], isDirectory: [false], canRead: [false]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.ClassLoaderFactory validateFile
WARNING: Problem with directory [/usr/share/tomcat8/common], exists: [false], isDirectory: [false], canRead: [false]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.ClassLoaderFactory validateFile
WARNING: Problem with directory [/usr/share/tomcat8/server/classes], exists: [false], isDirectory: [false], canRead: [false]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.ClassLoaderFactory validateFile
WARNING: Problem with directory [/usr/share/tomcat8/server], exists: [false], isDirectory: [false], canRead: [false]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.ClassLoaderFactory validateFile
WARNING: Problem with directory [/usr/share/tomcat8/shared/classes], exists: [false], isDirectory: [false], canRead: [false]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.ClassLoaderFactory validateFile
WARNING: Problem with directory [/usr/share/tomcat8/shared], exists: [false], isDirectory: [false], canRead: [false]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.Catalina initDirs
SEVERE: Cannot find specified temporary folder at /usr/share/tomcat8/temp
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.Catalina load
WARNING: Unable to load server configuration from [/usr/share/tomcat8/conf/server.xml]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.Catalina initDirs
SEVERE: Cannot find specified temporary folder at /usr/share/tomcat8/temp
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.Catalina load
WARNING: Unable to load server configuration from [/usr/share/tomcat8/conf/server.xml]
Nov 15, 2014 9:24:18 PM org.apache.catalina.startup.Catalina start
SEVERE: Cannot start server. Server instance is not configured.

Я понятия не имею, почему, но, похоже, Tomcat 8 в Ubuntu не настроен осмысленно. Все доступно, но нам нужны некоторые символические ссылки здесь и там, а также создание временного каталога. Это переводит в следующую инструкцию в Dockerfile:

RUN ln -s /var/lib/tomcat8/common $CATALINA_HOME/common && \
    ln -s /var/lib/tomcat8/server $CATALINA_HOME/server && \
    ln -s /var/lib/tomcat8/shared $CATALINA_HOME/shared && \
    ln -s /etc/tomcat8 $CATALINA_HOME/conf && \
    mkdir $CATALINA_HOME/temp

Последний трюк состоит в том, чтобы подключить разорванную папку веб-приложения, созданную Maven, к папке веб-приложений Tomcat, которую он ищет для развертывания:

RUN mkdir $CATALINA_HOME/webapps && \
    ln -s /vaadin7-workshop/target/workshop-7.2-1.0-SNAPSHOT/ $CATALINA_HOME/webapps/vaadinworkshop

На данный момент Святой Грааль не далеко, вам просто нужно просмотреть URL… если бы мы только знали, что это за IP. Начиная с работы на Mac, есть дополнительная виртуальная машина рядом с хостом и задействованным контейнером. Чтобы получить этот IP, введите:

$ boot2docker ip
 
The VM's Host only interface IP address is: 192.168.59.103

Теперь просмотр  http://192.168.59.103:8080/vaadinworkshop/  приведет нас к знакомому экрану семинара:

Развивается оттуда

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

docker run -v /Users/<login>/vaadin7-workshop:/vaadin7-workshop  -p 8080:8080 vaadinworkshop

Обратите внимание, что том хоста должен быть частью,  /Users и если он используется в OSX, он должен использовать  boot2docker v. 1.3+ .

К сожалению, кажется, что теперь это и есть showtopper, так как монтирование пустого каталога с хоста на контейнер не сделает каталог контейнера доступным с хоста. Напротив, он опустошит каталог контейнера, учитывая, что каталог хоста не существует … Кажется, есть  проблема  в Docker на Mac. При установке JHipster возникает та же проблема, и предлагается использовать  проект общего доступа к папкам Samba Docker .

Боюсь, мне было лень идти дальше. Тем не менее, это многому меня научило о Docker, его использовании и вариантах использования (а также об ограничениях интеграции с OSX). Для тех, кто заинтересован, вы найдете файл Docker ниже. Счастливого Докера!

FROM ubuntu:utopic
 
MAINTAINER Nicolas Frankel <nicolas [at] frankel (dot) ch>
 
# Config to get to install Java 8 w/o interaction
RUN echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu precise main" | tee -a /etc/apt/sources.list &&
echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | /usr/bin/debconf-set-selections &&
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886
 
RUN apt-get update &&
apt-get install -y --force-yes git oracle-java8-installer oracle-java8-set-default maven tomcat8
 
RUN git clone https://github.com/nfrankel/vaadin7-workshop.git
WORKDIR /vaadin7-workshop
RUN git checkout v7.2-1
RUN mvn package
 
ENV JAVA_HOME /usr/lib/jvm/java-8-oracle
ENV CATALINA_HOME /usr/share/tomcat8
ENV PATH $PATH:$CATALINA_HOME/bin
 
# Configure Tomcat 8 directories
RUN ln -s /var/lib/tomcat8/common $CATALINA_HOME/common &&
ln -s /var/lib/tomcat8/server $CATALINA_HOME/server &&
ln -s /var/lib/tomcat8/shared $CATALINA_HOME/shared &&
ln -s /etc/tomcat8 $CATALINA_HOME/conf &&
mkdir $CATALINA_HOME/temp &&
mkdir $CATALINA_HOME/webapps &&
ln -s /vaadin7-workshop/target/workshop-7.2-1.0-SNAPSHOT/ $CATALINA_HOME/webapps/vaadinworkshop
 
VOLUME ["/vaadin7-workshop"]
 
CMD ["catalina.sh", "run"]
 
# docker build -t vaadinworkshop .
# docker run -v ~/vaadin7-workshop training/webapp -p 8080:8080 vaadinworkshop