Первая часть: часть 1
Теперь вернемся к изучению образов.
Dockerfile
Докерфайлы — это инструкции для создания образа. Инструкции определяют точку старта и действия по конфигурированию образа. Рассмотрим пример:
Листинг 1. CentOS Dockerfile
FROM scratch MAINTAINER The CentOS Project <cloud -ops@centos.org> - ami_creator ADD centos-7-20150616_1752-docker.tar.xz / # Volumes for systemd # VOLUME ["/run", "/tmp"] # Environment for systemd # ENV container=docker # For systemd usage this changes to /usr/sbin/init # Keeping it as /bin/bash for compatibility with previous CMD ["/bin/bash"] |
Как видим, большинство инструкций — это комментарии. Есть, однако, 4 инструкции, не являющиеся комментариями:
1. FROM scratch. Все Dockerfile-ы происходят от базового образа. В нашем случае, образ CentOS происходит от “scratch” — корня всех образов. В общем-то это не операция, это указание на то, что данный образ (CentOS) является одним из корневых.
2. MAINTAINER … Указывает хозяина образа. В данном случае это владелец CentOS Project.
3. ADD centos…tar.xz: Директива ADD начинает загрузку файла внутрь образа, и, если он сжат, распаковку в указанный путь. В нашем случае начнется распаковка в корень файловой системы.
4. CMD [«/bin/bash»]: Этой командой запускается Bourne Again Shell (bash).
После того, как вы получили представление о структуре dockerfile, давайте разберем такой файл для Tomcat. Иерархия файла такая:
Она сложнее, чем можно ожидать, но при разборе понимаешь ее логику. Как вы уже знаете, корнем всех докерфайлов является scratch, который присутствует и тут. Первый смысловой образ — это debian:jessie. Официальные образы создаются из build pack, или стандартных образов. Это означает, что Docker не должен изобретать велосипед каждый раз при создании нового образа, ведь докер имеет прочное основание, на котором собирается новый образ. В нашем случае debian:jessie — это образ Debian который устанавливается точно так же, как CoreOS. Его докерфайл состоит из 3 строк:
Листинг 2. debian:jessie Dockerfile
FROM scratch ADD rootfs.tar.xz / CMD ["/bin/bash"] |
Для этого образа указаны 2 зависимости CURL и Source Code Management. Для buildpack-deps:jessie-curl докерфайл такой:
Листинг 3. buildpack-deps:jessie-curl Dockerfile
FROM debian:jessie RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ curl \ wget \ && rm -rf /var/lib/apt/lists/* |
Этот файл докера использует apt-get для установки curl и wget – они нужны для скачивания исходников и бинарников из интернета. Директива RUN запускает команду. В нашем случае, она обновляет библиотеки и устанавливает curl и wget.
Докерфайл для buildpack-deps:jessie-scp:
Листинг 4. buildpack-deps:jessie-scp Dockerfile
FROM buildpack-deps:jessie-curl RUN apt-get update && apt-get install -y --no-install-recommends \ bzr \ git \ mercurial \ openssh-client \ subversion \ && rm -rf /var/lib/apt/lists/* |
Этот файл докера устанавливает средства совместной разработки: Git, Mercurial, и Subversion.
Докерфайл для Java более навороченный:
Листинг 5. Java Dockerfile
FROM buildpack-deps:jessie-scm # A few problems with compiling Java from source: # 1. Oracle. Licensing prevents us from redistributing the official JDK. # 2. Compiling OpenJDK also requires the JDK to be installed, and it gets # really hairy. RUN apt-get update && apt-get install -y unzip && rm -rf /var/lib/apt/lists/* RUN echo 'deb http://httpredir.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list # Default to UTF-8 file.encoding ENV LANG C.UTF-8 ENV JAVA_VERSION 8u66 ENV JAVA_DEBIAN_VERSION 8u66-b01-1~bpo8+1 # see https://bugs.debian.org/775775 # and https://github.com/docker-library/java/issues/19#issuecomment-70546872 ENV CA_CERTIFICATES_JAVA_VERSION 20140324 RUN set -x \ && apt-get update \ && apt-get install -y \ openjdk-8-jdk="$JAVA_DEBIAN_VERSION" \ ca-certificates-java="$CA_CERTIFICATES_JAVA_VERSION" \ && rm -rf /var/lib/apt/lists/* # see CA_CERTIFICATES_JAVA_VERSION notes above RUN /var/lib/dpkg/info/ca-certificates-java.postinst configure # If you're reading this and have any feedback on how this image could be # improved, please open an issue or a pull request so we can discuss it! |
Из него нужно обратить внимание на команду apt-get install -y openjdk-8-jdk для скачивания и установки Java и добавочные действия для того, чтоб установка была секьюрной.
И, наконец, докерфайл для Tomcat:
Листинг 6. Tomcat Dockerfile
FROM java:7-jre ENV CATALINA_HOME /usr/local/tomcat ENV PATH $CATALINA_HOME/bin:$PATH RUN mkdir -p "$CATALINA_HOME" WORKDIR $CATALINA_HOME # see https://www.apache.org/dist/tomcat/tomcat-8/KEYS RUN gpg --keyserver pool.sks-keyservers.net --recv-keys \ 05AB33110949707C93A279E3D3EFE6B686867BA6 \ 07E48665A34DCAFAE522E5E6266191C37C037D42 \ 47309207D818FFD8DCD3F83F1931D684307A10A5 \ 541FBE7D8F78B25E055DDEE13C370389288584E7 \ 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 \ 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED \ 9BA44C2621385CB966EBA586F72C284D731FABEE \ A27677289986DB50844682F8ACB77FC2E86E29AC \ A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 \ DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 \ F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE \ F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23 ENV TOMCAT_MAJOR 8 ENV TOMCAT_VERSION 8.0.26 ENV TOMCAT_TGZ_URL https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz RUN set -x \ && curl -fSL "$TOMCAT_TGZ_URL" -o tomcat.tar.gz \ && curl -fSL "$TOMCAT_TGZ_URL.asc" -o tomcat.tar.gz.asc \ && gpg --verify tomcat.tar.gz.asc \ && tar -xvf tomcat.tar.gz --strip-components=1 \ && rm bin/*.bat \ && rm tomcat.tar.gz* EXPOSE 8080 CMD ["catalina.sh", "run"] |
Строго говоря, Tomcat использует родительский докерфайл Java 7 ссылка на dockerfile (версия latest для Java = 8, как видно из докерфайла для Java – листинг 5). Докерфайл устанавливает переменные окружения CATALINA_HOME и PATH с помощью директивы ENV. После этого он создает папку CATALINA_HOME. Директива WORKDIR меняет рабочую папку на CATALINA_HOME. Команда RUN выполняет ряд действий:
1. Скачивает TAR для Tomcat
2. Скачивает контрольную сумму
3. Проверяет, была ли успешной загрузка Tomcat TAR
4. Распаковывает TAR
5. Удаляет BAT файлы (работаем в linux, как никак)
6. Удаляет TAR (если распаковка прошла нормально, он больше не нужен).
Инструкции задаются в одной команде: докер видит ее и кеширует образ, который получается при выполнении команды. У Docker есть стратегия определения, какие образы нужно пересобрать и каждая инструкция проверяется во время сборки. Результат каждого шага кешируется для оптимизации, таким образом, если последний шаг в докерфайле изменен, докер может взять за основу наиболее завершенный образ и применить к нему только последний шаг. Недостатком такого подхода является то, что при изменении одной единственной команды из цепочки придется пересобирать весь образ.
Директива EXPOSE застявляет докер выставить наружу определенный порт после запуска контейнера. Как мы уже видели, надо было задать отображение физического порта на порт контейнера (параметр -p). Теперь командой EXPOSE мы указываем доступный порт на инстансе Docker.
После всего запускаем Tomcat, выполнив catalina.sh (он ожидается в папке PATH)
Короткое повторение пройденного
Построение докерфайла от начала до Томката было долгим процессом, нужно обобщить шаги:
1. Install Debian Linux.
2. Устанавливаем curl и wget.
3. Если вам нужны системы управления версиями, ставим их
4. Скачиваем и ставим Java.
5. Скачиваем и ставим Tomcat.
6. Прокидываем порт 8080 на инстансе Docker.
7. Запускаем Tomcat catalina.sh run.
Теперь вы стали экспертом по докеру — или, по крайне мере, кем-то реально крутым!
Будем пробовать собрать кастомный образ (custom image) докера с нашим приложением.
Разворачиваем свое приложение в Docker
Данное руководство больше посвящено разворачиванию приложения на Java, нежели написанию настоящего бизнес приложения на Java. Поэтому будет устанавливаться простое приложение с сервлетом Hello World. Вы можете посмотреть проект на Github ссылка. Никаких наворотов в исходниках: сервлет выводит банальное «Hello, World!». Гораздо интереснее используемый Dockerfile ссылка:
Листинг 7. Докерфайл для сервлета
FROM tomcat ADD deploy /usr/local/tomcat/webapps |
Ключевые моменты:
FROM tomcat показывает, что докерфайл берет за основу образ Tomcat
ADD deploy /usr/local/tomcat/webapps указывает докеру скопировать файлы из deploy в /usr/local/tomcat/webapps.
После клонирования репозитория запустите сборку:
mvn clean install |
После сборки появится файл target/helloworld.war, скопируйте его в папку проекта docker/deploy (ее надо будет создать). Теперь надо создать образ по инструкциям в докерфайле. Запустите из папки docker:
docker build -t lygado/docker-tomcat . |
Это инструкция сохдать новый образ из текущей папки (точка в конце команды) с тегом lygado/docker-tomcat. В данном случае lygado – это имя пользователя DockerHub, docker-tomcat – это имя образа. После выполения смотрим, что получилось:
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE lygado/docker-tomcat latest ccb455fabad9 42 seconds ago 849.5 MB |
Образ создан, запускаем:
docker run -d -p 8080:8080 lygado/docker-tomcat |
После запуска процесса смотрим работу сервлета по адресу (ваш IP может отличаться):
http://192.168.99.100:8080/helloworld/hello |
Вы можете остановить этот контейнер командой docker stop INSTANCE_ID.
Отправка образа в DockerHub
Если вы протестировали собранный образ и довольны результатами, вы можете сохранить его в репозитории:
docker push lygado/docker-tomcat |
После этого образ станет доступен всем (если только у вас не приватный репозиторий), в том числе и все аспекты разработки и развертывания вашего приложения в production.
В следующей части мы сделаем Docker частью процесса сборки: результатом сборки будет образ с нашим приложением.
Продолжение: часть 3