В статье пойдет речь о нашем опыте использования Docker для быстрой настройки масштабируемого dev окружения для web разработки. Я коротко расскажу о задачах, которые стояли перед нами и об инструментах, которые были выбраны для решения этих задач. Статья отмечена значком tutorial, потому что вы найдете в ней инструкцию по разворачиваю окружения у себя. По сравнению с аналогичными статьями (ссылки в конце статьи), здесь будет меньше технических деталей и больше живых примеров.
Какие задачи стояли перед нами
Бывает так, что к существующей команде подключается новый разработчик. Чтобы он смог начать выполнять задачи (проще говоря, писать код и проверять свою работу), мало получить исходники. Нужно окружение, которое включает в себя web-сервер, php компилятор и базу данных. Это минимальный набор. В зависимости от проекта в окружение могут входить:
- NoSQL;
- Сервер очередей;
- Движок полнотекстового поиска;
- Решение для кеширования;
- Сборщики;
- Полезные инструменты разработчика;
Все это должно устанавливаться локально у разработчика, и быть тех же версий, что и у остальных членов команды. И здесь возникают сложности:
- После установки, нужна настройка;
- ПО уже установлено, но оно другой версии;
- Это долго;
А то, что разработчики работают на разных платформах (windows, linux, os x), еще больше все усложняет.
Для решения задачи был выбран Docker. Пожалуй, основная причина это то, что он легко вписался в существующую инфраструктуру. Он прекрасно работает на Linux, а большинство наших разработчиков на этой ОС.
Альтернатива
Laravel предоставляет собственное решение для организации локального окружения под название Homestead. Это набор конфигов и скриптов для Vagrant, с помощью которых нужное ПО разворачивает в виртуальной машине VirtualBox. Но описание Homestead выходит за рамки данной статьи.
Проект Laradock
В начале этот проект был нацелен исключительно на запуск Laravel на Docker, что и отражено в его названии. Но по мере роста популярности в php сообществе Laradock стал поддерживать другие php-проекты: Symfony, CodeIgniter, WordPress, Drupal. Проект действительно популярный, активно поддерживается и развивается:
Laradock это набор предварительно настроенных, независимых Docker образов, которые можно подключать исходя из требований вашего проекта. Отлично документирован и предельно прост в использовании. Чтобы запустить компоненты, просто перечисляем их:
docker-compose up apache2 php-fpm mysql phpmyadmin
или
docker-compose up nginx php-fpm mariadb adminer
Замечание: нет необходимости в явном указании php-fpm, так как при запуске web server контейнеров php-fpm контейнер запускается автоматически.
В репозитории более 48 контейнеров, среди которых:
- Базы данных: MySQL, MariaDB, Percona, MongoDB, MSSQL, PostgreSQL
- Управление БД: PhpMyAdmin, Adminer, PgAdmin
- Web серверы: nginx, Apache2, Caddy
- PHP компиляторы: PHP FPM, HHVM
- Разное: Selenium, Jenkins, ElasticSearch, Kibana, Gitlab, Mailhog, MailDev, Laravel Echo, Phalcon
- Инструменты: PHP CLI, Composer, Git, Linuxbrew, Node, V8JS, Gulp, SQLite, xDebug, Envoy, Deployer, Vim, Yarn, Drush
Требования и начальные условия
Вам понадобятся:
- GIT
- Docker
и консоль, в которой будут выполняться команды. На сайте докера есть исчерпывающая документация по установке под разные платформы (ссылки тоже в конце статьи). Если у вас еще не установлен git, сделайте это по инструкции с официального сайта.
Архитектура git репозиториев: основной проект и Laradock
Laradock может использоваться в двух вариантах:
- Отдельный laradock на каждый проект
- Один laradock на множество проектов
В первом случае структура каталогов будет выглядеть так:
Во втором так:
Мы всегда используем первый вариант: один проект – один laradock. Именно такой подход обеспечивает гибкость и независимость одного проекта от другого.
Второй важный вопрос: создавать один общий репозиторий или два отдельных? Другими словами, нужно ли добавлять файлы laradock в основной репозиторий с проектом? Ответ – нужно, но в виде подмодуля к основному репозиторию. Docker-окружение это вспомогательная часть проекта и она требуется не всегда. Например на staging и production серверах в нем нет необходимости. При организации деплоя через git, файлы окружения туда не попадут.
Имя директории с окружением
По-умолчанию в именах контейнеров в качестве суффикса используется имя текущей директории: laradock_nginx_1, laradock_mysql_1 и т.п. Чтобы избежать путаницы данных внутри томов, необходимы уникальные названия каталогов для ваших окружений. Этого легко добиться, если придерживаться выбранной нами схемы: добавлять название проекта в имя каталога с окружением, например:
- laradock-mysite
- laradock-proj1
- laradock-mobapp
то есть префикс “laradock” и название каталога с проектом через дефис.
Запуск одного сайта
С чего мы начинаем запуск сайта?
Как мы упоминали в третьей главе, для создания окружения мы используем Laradoc.
Процесс запуска состоит из этапов настройки среды окружения и laravel-приложения.
Настройки проекта
В составе laradoc есть файл примера конфигурирования окружения. Мы создаём его копию для своего проекта
cp env-example .env
Параметры .env достаточно наглядны. В параметрах мы задаём доступы к базам данных, параметры электронной почты, доступы к сторонним сервисам, если используем в своём проекте.
Запуск и остановка приложений окружения производятся командами docker-compose
docker-compose up
и
docker-compose stop
По необходимости можно в команде запуска вызвать загрузку нужные сервисов. Например, так буду загружены три дополнительных сервиса:
docker-compose up -d nginx percona adminer
Можно убрать эту команду в отдельный shell-скрипт, чтобы не вводить каждый раз вручную.
Скрипт запуска можно назвать “start.sh”, или как вам удобно:
#!/usr/bin/env bash
docker-compose up -d nginx percona adminer;
Скрипт остановки сервисов можно назвать “stop.sh”, или “down.sh”:
#!/usr/bin/env bash
docker-compose stop;
Инициализация проекта
Переход в среду контейнера выполняется командой
docker-compose exec --user=laradock workspace bash
Ошибки при разворачивании
При установке Laradoc в среде linux может возникнуть проблема с правами доступа к файлам.
В таком случае у файлов может оказаться неверный владелец, или недостаточные права доступа.
Симптомы: при попытке запустить окружение командой “docker-compose up” или перейти в контейнер командой “docker-compose exec …”, как в примере выше возникают ошибки, аналогичные таким
/var/www/vendor does not exist and could not be created
The stream or file «/var/www/storage/logs/laravel.log» could not be opened: failed to open stream: Permission denied
Причина ошибки в том, что в примере конфигурации среды docker жёстко указывается ID Пользователя и Группы пользователей, по умолчанию — 1000 и 1000 соответственно.
Если же в нашей unix-системе эти ID уже заняты другими сущностями, то требуется вручную отредактировать конфигурацию.
Порядок устранения ошибки
Проверяем пользователя и группу у директорий:
ls -la /var/www
Владельцы файлов и каталогов (Пользователь и Группа пользователей) должны быть laradock laradock.
Если вместо laradock:laradock владелец и группа обозначены цифрами (1001:1001, 1001:13002 и подобные сочетания), то требуется внести правки в файлы настроек.
Если ID вашего Пользователя и Группы пользователей (/etc/passwd, /etc/group) не совпадают с указанными, то, для корректной работы, нужно внести правки в следующие файлы:
/laradock/php-fpm/Dockerfile*, в строке
«RUN usermod -u 1000 www-data»
заменить 1000 на ID пользователя
/laradock/.env в строках
WORKSPACE_PUID=1000
WORKSPACE_PGID=1000
WORKSPACE_PUID — указать ID вашего пользователя, WORKSPACE_PGID — ID группы пользователей
/laradock/workspace/Dockerfile*, в строках
ARG PUID=10315
ARG PGID=10004
PUID — ID пользователя, PGID — ID группы пользователей
После внесения правок заново пересобрать workspace и php-fpm и затем запустить контейнер:
docker-compose build workspace php-fpm
Если вы столкнулись с такой проблемой, то нужно проверить и права доступа к каталогам фреймворка Laravel. Устанавливаем права доступа на каталоги, для которых необходимы права на запись:
sudo chgrp -R www-data storage bootstrap/cache; sudo chmod -R ug+rwx storage bootstrap/cache
SSL сертификаты и https
Скорее всего ваш сайт в production будет работать по безопасному протоколу. Имеет смысл и локальную разработку вести на https. Это не очень сложно сделать, нужен SSL сертификат и небольшие настройки. Подробнее описано в этой статье Как выпустить самоподписанный SSL сертификат.
Запуск нескольких сайтов
Итак, все проекты работают по схеме “Один Laradock – один проект”. Но один проект это не обязательно один сайт. Иногда нужно запустить несколько сайтов одновременно, потому что они будут взаимодействовать между собой.
В этом случае два laradock одновременно не запустить, потому что в каждом из них запущен web-сервер, который слушает 80-ый порт – получаем конфликт. Но у нас есть доступ к конфигам nginx, давайте настроим его.
Но сначала замечание об архитектуре и git-репозиториях. В случае нескольких сайтов, используем структуру каталогов из второго варианта:
Git-репозиторий с laradock больше не подмодуль другого репозитория, а становится полностью самостоятельным.
Настройка web-сервера будет показана на примере nginx. В каталоге laradock переходим в nginx/sites. Видим default.conf и несколько *.conf.example файлов. На основе default.conf или файлов примеров создаем конфигурации для сайтов.
Обратите внимание на document root. По умолчанию директива root выглядит так:
root /var/www/public;
а должна так:
root /var/www/site-1/public;
root /var/www/site-2/public;
Важно!
Посмотрите на содержимое .gitignore в этом каталоге. Все *.conf файлы, кроме default.conf игнорируются. Нужно добавить в исключения созданные файлы, то есть не игнорировать их.
Настроим crontab, чтобы планировщик laravel мог корректно работать. Для этого в файле workspace/crontab/laradock добавим пути:
* * * * * laradock /usr/bin/php /var/www/site-1/artisan schedule:run >> /dev/null 2>&1
* * * * * laradock /usr/bin/php /var/www/site-2/artisan schedule:run >> /dev/null 2>&1
Для успешной коммуникации сайтов внутри контейнеров, добавим алиасы. В файле docker-compose.yml находим раздел
### NGINX Server ###
и добавляем алиас на каждый домен:
Это все, что нужно сделать для запуска проекта с несколькими доменами. За рамками статьи остается вопрос организации https для нескольких доменов. Все по аналогии с организацией ssl для одного домена, который описан в разделе выше. Добавьте комментарий, если возникнут сложности, я отвечу на него или опишу особенности в отдельной статье.
Дополнительные возможности
В пространстве окружения Docker возможно настроить необходимые нам приложения. В базовую конфигурацию Laradoc уже входят пакеты приложений:
Сервер веб-приложений
Apache2, Caddy
Кэширование веб-приложений
Nginx, Varnish
Базы данных и кэширующие сервисы
Mongo, Redis, Mssql, Mysql, Percona, Mariadb, Elasticsearch, Memcached, Redis, RethinkDb, Aerospike
Веб-интерфейсы к базам данных
Adminer, PhpMyAdmin
Балансировщик нагрузки
Haproxy
Программирование, программные оболочки и фреймворки
Php, Python, Symfony, Laravel, Node
Утилиты
Php, Python, Symfony, Laravel, Node
Менеджер пакетов
Yarn, Composer
Средство тестирования
Jenkins
Средство конфигурирования инфраструктурой приложения
Terraform
Кратко рассмотрим самые упоминаемые приложения.
RabbitMQ
Механизм обмена сообщениями между приложениями. Разработчик этого пакета определяет его назначение так: «менеджер очередей» (queue manager), «брокер сообщений» (message broker) или «очереди сообщений» (message-queueing).
Сообщение может содержать любой набор данных.
В сценарии работы с менеджером очередей сообщение от одного приложения — отправителя — сохраняется до тех пор, пока другое приложение (получатель), не подключиться и не заберёт (получит) сообщение из очереди.
Redis
Создание кэша данных в оперативной памяти. Может, также, использоваться в качестве хранилища данных наряду с сервером баз данных, либо заменяя его.
Redis поддерживает строки, списки, множества, упорядоченные множества и хэш-таблицы.
Основной недостаток редис — потеря данных в случае очистки оперативной памяти, при перезагрузке ОС или при выключении оборудования. Разработчики редис предусмотрели подобный сценарий: в режиме AOF (Append Only File) данные добавляются в дисковый файл каждую секунду.
Основное преимущество редис — максимально быстрый доступ к данным со скоростью обращения к ОЗУ.
Заключение
Выбрав для веб-разработки решение Laravel + Docker, мы выиграли самый ценный приз: время.
Следуя сценарию разработки в WAMP или LAMP, нам приходилось тратить время
бесполезно и в никуда.
И WAMP, и LAMP требует от php-разработчика определённого уровня квалификации в областях, которые не связаны напрямую с веб-разработкой: конфигурирование веб-сервера, настройка параметров php и т. п.
Использование Laradoc позволяет нам, однажды создав всю среду проекта, в минимальный срок развернуть его на новом рабочем месте. И сразу же приступить к работе.
В заключении, отметим преимущества использования Laradoc:
- унифицированная, на каждом рабочем месте, инфраструктура: веб-сервер, sql-сервер, набор фреймворков и библиотек;
- рациональное использование рабочего времени;
- быстрый вход нового разработчика в проект.
Напишите в комментариях, как у вас в команде организована работа с окружением, какие инструменты и подходы используете.