Статьи

Docker и Dockerfiles — это просто!

Для разработчиков стало второй натурой использовать виртуальные машины для настройки и управления своей рабочей средой. Большинство профессионалов, которые используют виртуальные машины, используют Vagrant для работы со средами разработки. В этой статье мы перейдем от Vagrant к Docker и воспользуемся небольшим приложением Laravel, чтобы проверить, что все работает так, как ожидалось.

Docker Logo

Установка

Страница установки содержит инструкции практически для всех популярных платформ. Docker изначально работает в ОС Linux, но мы можем использовать его в Windows и Mac OS, установив утилиту Docker Toolbox. Если вы столкнулись с некоторыми проблемами, вы можете посетить эту статью, в которой освещаются наиболее распространенные проблемы. Вы можете убедиться, что он установлен и работает, выполнив следующую команду в своем терминале.

docker - v 
 # output 
 Docker  version 1.8 . 1 ,  build d12ea79 

Докер машины

Docker-машина — это виртуальная машина, в которой хранятся ваши образы и контейнеры (подробнее об этом позже). Давайте создадим нашу первую виртуальную машину.

 docker - machine create -- driver virtualbox docker - vm 

Вы можете изменить параметры driver зависимости от ваших предпочтений. Смотрите здесь список доступных драйверов .

Вы можете распечатать конфигурацию машины, выполнив команду docker-machine env docker-vm . Вот как вы можете переключаться между машинами.

 # Use the docker-vm 
 eval   "$(docker-machine env docker-vm)" 

 # Switch to the dev machine 
 eval   "$(docker-machine env dev)" 

Вы можете прочитать больше о команде docker-machine в документации и объяснить, почему мы используем eval можно на этой странице .

Docker Images

Образы Docker — это блоки ОС, которые содержат предварительно установленное и настроенное программное обеспечение. Вы можете просмотреть список доступных изображений в Docker Hub . Фактически вы можете создать свой собственный образ на основе другого и отправить его в концентратор Docker, чтобы его могли использовать другие пользователи.

Команда docker images выводит список доступных изображений на вашем компьютере, и вы можете загрузить новый docker pull <image name> из концентратора с помощью команды docker pull <image name> . Для нашего демонстрационного приложения мы nimmis/apache-php5 изображения mysql и nimmis/apache-php5 .

Docker images

Контейнеры Docker

Контейнеры Docker — это отдельные экземпляры, которые мы создаем из изображений. Они также могут стать хорошей отправной точкой для создания нового персонализированного образа, который могут использовать другие. Вы можете просмотреть список доступных контейнеров, используя команду docker ps . Это только список запущенных контейнеров, но вы можете перечислить все доступные, добавив флаг -a ( docker ps -a ).

Docker containers

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

 # Get image from the hub docker pull nimmis / apache - php5 # Create the container docker run - tid nimmis / apache - php5 # List running containers docker ps 

Первая команда может занять некоторое время, чтобы завершить загрузку изображения из концентратора. Первый флаг ( t ), который мы указали во второй команде, означает, что мы хотим выделить TTY для взаимодействия с контейнером, второй флаг ( i ) означает, что нам нужен интерактивный STDIN / OUT, а последний ( d ) означает что мы хотим запустить его в фоновом режиме.

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

Опция -P в команде run автоматически выставит все порты, необходимые из контейнера, на хост-машину, а опция -p позволяет вам указать порты, которые будут доступны из контейнера для хоста.

 # Automatically exposes the container ports to an available host port docker run - tid - P nimmis / apache - php5 # We can also specify ports manually <host port>:<container port> docker run - tid - p 80 : 80  nimmis / apache - php5 

Теперь вы можете получить доступ к контейнеру, используя адрес docker-machine ip docker-vm и указанный порт. Если вы не знаете порт, вы можете запустить команду docker ps и посмотреть столбец ports .

Apache server

Объем контейнера

Тома — это простой способ разделить хранилище между вашим хостом и контейнером. Они инициализируются при создании контейнера и синхронизируются. В нашем случае мы хотим смонтировать /var/www в локальный каталог ~/Desktop/www/laravel_demo .

 # Option syntax docker run - v < local  dir >:< container dir > 

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

 docker run - tid - p 80 : 80   - v ~/ Desktop / www / laravel_demo :/ var / www nimmis / apache - php5 

Laravel Demo screenshot

Примечание . Директива Apache DocumentRoot умолчанию указывает на /var/www/html , поэтому вы должны изменить ее на /var/www/public в /etc/apache2/sites-enabled/000-default.conf конфигурации /etc/apache2/sites-enabled/000-default.conf и перезапустить Apache , Вы можете войти в контейнер с помощью команды exec .

 docker exec - it < container >  bash 
 # Restart Apache 
 / etc / init . d / apache2 restart 

Именование Контейнеров

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

 # Option syntax docker run -- name < container name > 

Итак, наша полная команда будет выглядеть следующим образом.

 docker run - tid - p 80 : 80   - v ~/ Desktop / www / laravel_demo :/ var / www -- name wazo_server nimmis / apache - php5 

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

 docker start wazo_server 

Контейнер базы данных

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

Мы создаем контейнер MySQL так же, как и выше. Мы монтируем папку /var/lib/mysql в локальную папку на нашем хост-компьютере, чтобы синхронизировать данные между двумя компьютерами. В случае потери данных мы можем смонтировать ту же локальную папку в другой контейнер.

 docker run - p 3306 : 3306   -- name mysqlserver - e MYSQL_ROOT_PASSWORD = root - d mysql 

Опция -e позволяет вам установить переменную среды при создании контейнера. В этом случае MYSQL_ROOT_PASSWORD сообщит процессу установки MySQL использовать пароль, который мы указали в команде.

Теперь, если вы хотите подключиться к базе данных извне, вы можете использовать адрес, возвращенный командой docker-machine ip docker-vm и открытый порт в команде docker run . Моя конфигурация базы данных будет выглядеть следующим образом.

 // .env DB_HOST = 192.168 . 59.103 DB_DATABASE = demo DB_USERNAME = root DB_PASSWORD = root 

Вы можете проверить, что все работает, запустив команду переноса базы данных Laravel, и убедитесь, что ваш контейнер mysql запущен.

 ./ artisan migrate 

Artisan migrate

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

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

 # Option syntax docker run -- link < container name or ID >:< alias > 
 # Create MySQL container first. docker run - p 3306 : 3306   -- name mysqlserver - e MYSQL_ROOT_PASSWORD = root - d mysql # Create web server container docker run - tid - p 80 : 80   - v ~/ Desktop / www / laravel_demo :/ var / www -- name wazo_server -- link mysqlserver : mysqldb nimmis / apache - php5 

Новая опция здесь --link <container>:<env alias> . Псевдоним среды будет префиксом ваших переменных среды подключения, в нашем случае mysqldb . Вы можете войти в контейнер веб-сервера и запустить printenv | grep MYSQLDB printenv | grep MYSQLDB для печати всех переменных связывания MySQL.

 # Log into the web server docker exec -- it wazo_server bash # Print environment variables printenv |  grep MYSQLDB 

Link env

Пакет Dotenv , используемый Laravel, позволяет вкладывать переменные окружения. Это означает, что мы можем добавить нашу переменную окружения в файл .env .

 // .env DB_HOST = "{$MYSQLDB_PORT_3306_TCP_ADDR}" DB_DATABASE = demo DB_USERNAME = root DB_PASSWORD = "{$MYSQLDB_ENV_MYSQL_ROOT_PASSWORD}" 

Выполнение команды ./artisan migrate из командной строки дает следующий результат.

Artisan migrate

Dockerfiles

Теперь, когда мы узнали, как работать с образами Docker, контейнерами и как их связывать, мы узнаем, как использовать Dockerfiles для создания персонализированных образов и Docker compose для управления нашими контейнерами.

Dockerfiles помогут вам создавать и делиться системными образами, похожими на Vagrant. Мы выделим основные команды, используемые для настройки образа Docker. В этом примере мы собираемся создать изображение Laravel 5. Вы можете проверить окончательный код на Github, если хотите следовать.

ИЗ

Инструкция FROM позволяет выбрать базовое изображение для начала. Мы можем начать с простого образа, такого как Ubuntu:14.04 или мы можем начать с изображения, на котором уже установлены и настроены Apache / NGINX и PHP. Мы будем использовать образ Ubuntu для нашего примера.

 FROM ubuntu : 14.04 

MAINTAINER

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

 MAINTAINER RAFIE Younes   < younes . rafie@gmail . com > 

ENV

Инструкция ENV позволяет определить переменную среды, к которой вы можете получить доступ в процессе установки. В нашем случае мы будем использовать его для указания версии Laravel, которую мы хотим установить, и вы также можете изменить ее и создать другую версию для Laravel 4.

 ENV LARAVEL_VERSION ~ 5.1 . 0 

БЕГАТЬ

Инструкция RUN позволяет нам запускать команды на оболочке (не bash). Вы можете запустить команду вроде RUN apt-get update , но если вы хотите использовать bash, вы должны использовать ее в качестве следующего RUN ["/bin/bash", "-c", "apt-get update"] .

 RUN apt - get update &&  \ apt - get - y install apache2 php5 libapache2 - mod - php5 php5 - mcrypt php5 - json curl git &&  \ apt - get clean &&  \ update - rc . d apache2 defaults &&  \ php5enmod mcrypt &&  \ rm - rf / var / www / html &&  \ curl - sS https :// getcomposer . org / installer |  php &&  \ mv composer . phar / usr / local / bin / composer 

После установки Apache, PHP и других расширений нам нужно настроить виртуальный хост и указать нашу общую папку. Давайте создадим файл с именем 000-default.conf содержащий необходимую конфигурацию.

 <VirtualHost  *:80 > ServerAdmin webmaster@localhost DocumentRoot /var/www/laravel/public ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined <Directory   / var / www / laravel > Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> 
 </VirtualHost> 

COPY

Инструкция COPY полезна в случае выше, нам нужно только указать исходный файл (ы) и место назначения.

 COPY 000 - default . conf / etc / apache2 / sites - available / 000 - default . conf 

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

 COPY *. conf / etc / apache2 / sites - available / 

WORKDIR

Вы можете использовать WORKDIR для перемещения в другой каталог, чтобы продолжить создание образа. Мы используем его для перемещения в каталог /var/www для установки Laravel с помощью Composer.

 WORKDIR / var / www RUN composer create - project laravel / laravel laravel $LARAVEL_VERSION -- prefer - dist -- no - interaction &&  \ php laravel / artisan key : generate &&  \ chown www - data : www - data - R laravel / storage 

После перехода в /var/www мы устанавливаем Laravel и делаем необходимые папки доступными для записи пользователем Apache www-data . Если вы заметили, мы использовали флаг --no-interaction на Composer, чтобы избежать каких-либо вопросов по установке.

ПОДВЕРГАТЬ

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

 EXPOSE 80 EXPOSE 443 

Мы выставляем наш сервер через стандартный HTTP-порт 80, и мы также разрешаем HTTPS-соединения через порт 443.

CMD

Инструкция CMD может использоваться для инициализации контейнера. В нашем случае мы будем использовать его для запуска нашего сервера Apache в фоновом режиме.

 CMD [ "/usr/sbin/apache2ctl" ,   "-D" ,   "FOREGROUND" ] 

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

ВХОДНАЯ ТОЧКА

Инструкция ENTRYPOINT позволяет указать команду, которая будет выполняться, когда пользователь запускает образ Docker. Мы можем использовать его для обновления наших зависимостей Composer.

 //  setup - laravel . sh #!/bin/bash cd / var / www / laravel composer update 
 COPY setup - laravel . sh / setup - laravel . sh # Copy the local file to the image RUN [ "chmod" ,   "+x" ,   "/setup-laravel.sh" ]   # Make sure it's executable ENTRYPOINT [ "/setup-laravel.sh" ] 

Вы можете пройти через все доступные инструкции в документации . В следующем разделе мы увидим, как использовать Docker Compose для управления нашими контейнерами.

Docker Compose

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

Мы начнем с создания файла docker-compose.yml который будет содержать нашу конфигурацию. Docker Compose использует YAML для файлов конфигурации, вы можете проверить официальную документацию, если вы с ней не знакомы.
Первый узел определяет имя службы; это может быть что угодно. В данном случае это называется web . Дочерний узел build указывает источник изображения, и вы можете выбрать изображение из концентратора Docker или из пути Dockerfile, чтобы создать изображение.

 web : build :   . 

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

 web : build :   . ports : 
     -   "80:80" 
     -   "443:443" 

Мы говорили об увеличении объемов в первой части; мы можем указать это и в нашем файле docker-compose .

 web : build :   . ports : 
     -   "80:80" 
     -   "443:443" volumes : 
     -   ./ laravel :/ var / www / laravel 

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

 web : build :   . ports : 
     -   "80:80" 
     -   "443:443" volumes : 
     -   ./ laravel :/ var / www / laravel links : 
     -  mysqldb : mysqldb 

Вы указываете ссылки в виде <container name>:<env alias> . Последняя часть заключается в создании контейнера mysqldb .

 mysqldb : image :  mysql environment : 
     -  MYSQL_ROOT_PASSWORD = root 

Обратите внимание, что мы использовали environment для отправки MYSQL_ROOT_PASSWORD к изображению. Вы можете использовать эту опцию, чтобы создать общий образ Laravel, который может установить любую версию Laravel.

Если у вас уже есть существующий контейнер, который вы хотите связать, вы можете использовать конфигурацию external_links .

Теперь мы готовы построить наш образ и создать контейнеры, чтобы проверить, что все работает, как ожидалось. Запустите команду docker-compose up внутри папки проекта, чтобы создать образ и создать контейнеры. Это может занять некоторое время, прежде чем все будет установлено. Вы можете увидеть запущенные контейнеры, запустив docker ps и образ сборки, используя docker images из терминала.

Вывод

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

Docker Compose — это новый инструмент, который все еще разрабатывается и совершенствуется, чтобы избавить от проблем управления и портирования сред разработки. Вы можете проверить документацию для получения более подробной информации и ссылки на файл Docker Compose YML, чтобы увидеть список поддерживаемых свойств. Общие документы по Docker смотрите здесь .

Если вы уже пробовали Docker и Docker Compose, мы будем рады узнать, что вы о них думаете! Если у вас есть какие-либо вопросы или комментарии, пожалуйста, оставьте их ниже!