
О чем эта статья
В статье пойдет речь о нашем опыте использования 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 репозиториев: основной проект и 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;
Важно!Настроим crontab, чтобы планировщик laravel мог корректно работать. Для этого в файле workspace/crontab/laradock добавим пути:
Посмотрите на содержимое .gitignore в этом каталоге. Все *.conf файлы, кроме default.conf игнорируются. Нужно добавить в исключения созданные файлы, то есть не игнорировать их.
* * * * * 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
Laradock
Laravel Homestead
«Как выпустить самоподписанный SSL сертификат и заставить ваш браузер доверять ему»
Docker + Laravel =
Заключение
Выбрав для веб-разработки решение Laravel + Docker, мы выиграли самый ценный приз: время.
Следуя сценарию разработки в WAMP или LAMP, нам приходилось тратить время
бесполезно и в никуда.
И WAMP, и LAMP требует от php-разработчика определённого уровня квалификации в областях, которые не связаны напрямую с веб-разработкой: конфигурирование веб-сервера, настройка параметров php и т. п.
Использование Laradoc позволяет нам, однажды создав всю среду проекта, в минимальный срок развернуть его на новом рабочем месте. И сразу же приступить к работе.
В заключении, отметим преимущества использования Laradoc:
- унифицированная, на каждом рабочем месте, инфраструктура: веб-сервер, sql-сервер, набор фреймворков и библиотек;
- рациональное использование рабочего времени;
- быстрый вход нового разработчика в проект.
Напишите в комментариях, как у вас в команде организована работа с окружением, какие инструменты и подходы используете.