Настройка окружения для PHP разработчиков

от автора

В данной статье мы рассмотрим настройку окружения для PHP разработчиков с использованием Vagrant, Docker, Xdebug, PHPUnit, и интеграцию с IDE PHPStorm.

+

Требования

  • Окружение должно развертываться на Windows, MacOS, Linux
  • Установка должна быть максимально простой
  • Быстрая работа с файловой системой
  • Интеграция с IDE PHPStorm
  • Несколько версии PHP интерпретаторов (5.6, 7.0)

Подготовка

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

Что входит в сборку?

  • Nginx
  • MySQL 5 (Percona)
  • MongoDB 3
  • Redis 3
  • PHP 5.6, 7.0 CLI + FPM

PHP-extensions

5.6

  • cli
  • fpm
  • bcmath
  • gd
  • gmp
  • intl
  • mbstring
  • mcrypt
  • pdo
  • mysqlnd
  • crypto
  • geoip
  • imagick
  • jsonc
  • memcache
  • memcached
  • mongodb
  • ssh2
  • xdebug
  • soap
  • xml
  • opcache
  • redis
7.0

  • cli
  • fpm
  • bcmath
  • gd
  • gmp
  • intl
  • mbstring
  • mcrypt
  • pdo
  • mysqlnd
  • crypto
  • geoip
  • imagick
  • memcache
  • memcached
  • mongodb
  • ssh2
  • xdebug
  • soap
  • xml
  • opcache
  • redis

Настройка и конфигурирование

Внимание! Все описанные настройки и файлы выложены на GitHub. Если у вас возникают вопросы по использованию Vagrant или Docker обратитесь к официальной документации.

Развертывание окружения чуть-чуть отличается на разных ОС:

  • MacOS все пройдет, как положено без дополнительных действий.
  • Windows необходимо запустить вспомогательный скрипт hosts-set.cmd для установки прав текущему пользователю на запись для hosts файла до запуска vagrant up, также если у вас имя текущего пользователя содержит любые символы non-ACSII, то вам придется сменить путь до вашей рабочей директории vagrant.d используя переменную окружения VAGRANT_HOME.
  • Linux на усмотрение, можно поставить Vagrant с NFS сервером или просто использовать docker-compose инструкции.

hosts-set.cmd

@if (1==1) @if(1==0) @ELSE @echo off&SETLOCAL ENABLEEXTENSIONS >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"||(     cscript //E:JScript //nologo "%~f0"     @goto :EOF ) CACLS %SystemRoot%\system32\drivers\etc\hosts /E /G %USERNAME%:W @goto :EOF @end @ELSE ShA=new ActiveXObject("Shell.Application") ShA.ShellExecute("cmd.exe","/c \""+WScript.ScriptFullName+"\"","","runas",5); WScript.Sleep(500) @end 

Гостевая ОС будет работать на Ubuntu 14.04 (Trusty), статическом IP адресе 10.0.0.2 и в качестве share-папки будем использовать монтирование через NFS.

Для удобства создайте папку под названием dockrant (Docker + Vagrant = Dockrant), далее в статье мы будем отталкиваться от этой папки.

Определимся со структурой папок:

./dockrant — наша корневая папка
./dockrant/ssh — SSH ключики для гостевой ОС (в данном туториале используем стандартные ключи vagrant)
./dockrant/share — share-папка между хост и гостевой ОС
./dockrant/share/tools — папка с нашими инструментами и bash скриптами
./dockrant/vagrant/build —  исполняемые bash скрипты при поднятии гостевой ОС

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

./dockrant/ssh — положим два файла id_rsa (приватный ключ) и id_rsa.pub (публичный ключ)

id_rsa

-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2 hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1 Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf 4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX 3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj 3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+ dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz 6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH +vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s= -----END RSA PRIVATE KEY-----
id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key

./dockrant/share/ — создадим файл phpinfo.php с phpinfo() функцией, чтобы потом проверить работоспособность

phpinfo.php

<?php phpinfo(); 

./dockrant/share/tools/ — положим несколько вспомогательных скриптов для запуска PHP интерпретаторов из под Docker exec и PHPUnit (скачайте c сайта phpunit.phar)

php56

#!/bin/bash CMD="export IDE_PHPUNIT_PHPUNIT_PHAR='$IDE_PHPUNIT_PHPUNIT_PHAR'" CMD+=" && export IDE_PHPUNIT_VERSION='$IDE_PHPUNIT_VERSION'" CMD+=" && export SSH_CLIENT='$SSH_CLIENT'" CMD+=" && export JETBRAINS_REMOTE_RUN='$JETBRAINS_REMOTE_RUN'" CMD+=" && export DEBUG_CONFIG='$XDEBUG_CONFIG'" CMD+=" && export XDEBUG_CONFIG='$XDEBUG_CONFIG'" CMD+=" && php56 $@" docker exec share_php_1 bash -c "$CMD" 
php56tty

#!/bin/bash CMD+="php56 $@" docker exec -t -i share_php_1 bash -c "$CMD" 
php70

#!/bin/bash CMD="export IDE_PHPUNIT_PHPUNIT_PHAR='$IDE_PHPUNIT_PHPUNIT_PHAR'" CMD+=" && export IDE_PHPUNIT_VERSION='$IDE_PHPUNIT_VERSION'" CMD+=" && export SSH_CLIENT='$SSH_CLIENT'" CMD+=" && export JETBRAINS_REMOTE_RUN='$JETBRAINS_REMOTE_RUN'" CMD+=" && export DEBUG_CONFIG='$XDEBUG_CONFIG'" CMD+=" && export XDEBUG_CONFIG='$XDEBUG_CONFIG'" CMD+=" && php70 $@" docker exec share_php_1 bash -c "$CMD" 
php70tty

#!/bin/bash CMD+="php70 $@" docker exec -t -i share_php_1 bash -c "$CMD" 

Для php* скриптов мы не используем TTY, эти скрипты нужны для корректной настройки интеграции с IDE в использовании remote интерпретаторов, скрипты php*tty нужны для ручного использования запуска PHP скриптов, в том числе и в интерактивном режиме php -a.

./dockrant/vagrant/build/php/ — положим init.sh bash скрипт для копирования исполняемых файлов запуска PHP интерпретаторов.

init.sh

#!/bin/bash cp /share/tools/php56 /usr/bin/php56 && chmod +x /usr/bin/php56 cp /share/tools/php70 /usr/bin/php70 && chmod +x /usr/bin/php70 cp /share/tools/php56tty /usr/bin/php56tty && chmod +x /usr/bin/php56tty cp /share/tools/php70tty /usr/bin/php70tty && chmod +x /usr/bin/php70tty 

./dockrant/vagrant/build/docker/ — положим init.sh и docker-compose.sh bash скрипты для установки docker-compose и команд на сборку контейнеров при поднятии гостевой ОС.

init.sh

#!/bin/bash /usr/local/bin/docker-compose -f /share/docker-compose.yml build /usr/local/bin/docker-compose -f /share/docker-compose.yml up -d 
docker-compose.sh

#!/bin/bash curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose 

Docker-compose

Создадим файл ./dockrant/share/docker-compose.yml

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

Собираем из следующих образов:

  • redis:3
  • percona:5
  • gurukami/php:5.6
  • gurukami/php:7.0 (для FPM используется по умолчанию)
  • gurukami/nginx
  • mongo:3

docker-compose.yml

version: '2' services:   redis:     image: redis:3.0   mysql:     image: percona:5     environment:       - MYSQL_ROOT_PASSWORD=gurukami     volumes:       - /share:/share   php56:     image: gurukami/php:5.6     links:       - mysql       - mongo       - redis     volumes:       - /share:/share       - /home:/home       - /tmp/:/tmp/   php:     image: gurukami/php:7.0     links:       - mysql       - mongo       - redis     volumes:       - /share:/share       - /home:/home       - /tmp/:/tmp/   mongo:     image: mongo:3     ports:       - "27017:27017"   nginx:     image: gurukami/nginx:latest     depends_on:       - php     links:       - php     ports:       - "80:80"       - "443:443"     volumes:       - /share:/share 

Vagrantfile

Создайте в папке dockrant файл Vagrantfile и запишите туда следующие инструкции

Vagrantfile

Vagrant.require_version ">= 1.8.6"  required_plugins = %w(vagrant-hostsupdater) plugins_to_install = required_plugins.select { |plugin| not Vagrant.has_plugin? plugin } if not plugins_to_install.empty?   puts "Installing plugins: #{plugins_to_install.join(' ')}"   if system "vagrant plugin install #{plugins_to_install.join(' ')}"     exec "vagrant #{ARGV.join(' ')}"   else     abort "Installation of one or more plugins has failed. Aborting."   end end  Vagrant.configure(2) do |config|    config.vm.box = "ubuntu/trusty64"   config.vm.hostname = "gurukami.local"    config.ssh.insert_key = false    config.hostsupdater.aliases = [     "sandbox.local"   ]    config.nfs.map_uid = Process.uid   config.nfs.map_gid = Process.gid    config.vm.network :private_network, ip: "10.0.0.2"   config.vm.network :forwarded_port, guest: 22, host: 2202, id: "ssh"    config.vm.provider :virtualbox do |vb|     vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]     vb.name = "Gurukami (Dockrant)"     vb.memory = 1024     vb.cpus = 2   end    config.vm.provision "fix-no-tty", type: "shell" do |s|     s.privileged = false     s.inline = "sudo sed -i '/tty/!s/mesg n/tty -s \\&\\& mesg n/' /root/.profile"   end    config.vm.provision "shell", inline: 'mkdir /vagrant', run: "once"   config.vm.provision "shell", inline: 'echo "nameserver 8.8.8.8" >> /etc/resolv.conf', run: "always"   config.vm.provision "shell", path: './vagrant/build/php/init.sh', run: "once"   config.vm.provision "shell", path: './vagrant/build/docker/docker-compose.sh', run: "once"    config.vm.provision :docker   config.vm.provision "shell", path: './vagrant/build/docker/init.sh', run: "always"    config.vm.synced_folder ".", "/vagrant", disabled: true   config.vm.synced_folder "./share", "/share", nfs: true, nfs_udp: false end 

Тюнинг:

  • При необходимости шаринга можно добавить опцию config.vm.network :public_network, чтобы поднять на публичном интерфейсе или использовать vagrant share
  • Увеличить использование выделенной памяти vb.memory, по умолчанию стоит 1024 MB
  • Увеличить кол-во использованных процессоров vb.cpus, по умолчанию стоит 2

Запуск

В папке dockrant запускаем команду

vagrant up --provider virtualbox

После сборки откроем в браузере — sandbox.local/phpinfo.php

Docker-machine

Для того чтобы наша виртуальная машина работала как docker-machine нам необходимо добавить её используя generic драйвер, запускаем из под папки dockrant

docker-machine create --driver generic --generic-ip-address=10.0.0.2 --generic-ssh-key ./ssh/id_rsa --generic-ssh-user vagrant sandbox

После создания docker-machine, гостевую машину нужно перезагрузить, т.к. после установки все docker контейнеры останавливаются

vagrant reload

PHP-CLI

Запуск PHP скриптов осуществляется на гостевой машине (10.0.0.2), помните, что между хост-машиной и гостевой есть /share папка.

php56 /path/to/file php70 /path/to/file 

Запуск PHP интерпретаторов в интерактивном режиме

php56tty -a php70tty -a 

Интеграция с PHPStorm

Мы настроим дебаггер с помощью XDebug, прикрутим PHPUnit а также добавим управление нашими контейнерами через плагин Docker Integration, с помощью которого можно будет смотреть логи наших сервисов, перезагружать контейнеры, исполнять скрипты.

Добавим в настройки наши PHP интерпретаторы, открываем настройки Languages & Frameworks → PHP

Добавляем сначала 5.6 версию, потом повторяем для версии 7.0, нажимаем на кнопку

Затем нажав на + выбираем Remote…

В всплывающем окне выбираем тип Vagrant и указываем путь до PHP интерпретатора на гостевой ОС /usr/bin/php56

Теперь добавим наш удаленный сервер в список для работы с дебаггером по запросу из браузера
Language & Frameworks → PHP → Servers. Пропишем path mappings до нашей /share папки чтобы IDE смог распознать запросы по путям между хост машиной и гостевой

Настроим PHPUnit, идем в настройки Language & Frameworks → PHP → PHPUnit и для каждой версии PHP интерпретатора пропишем путь до /share/tools/phpunit.phar

Мы почти готовы к отладке нашего приложения, но еще осталось настроить конфигурации запуска

Настроим удаленную отладку PHP Remote Debug

Ставим breakpoint к примеру в файле phpinfo.php на 2 строчке, запускаем дебаггер, переходим в браузере на страницу sandbox.local/phpinfo.php и видим, что наш дебаггер сработал в IDE

Теперь перейдем к PHPUnit

Создадим проcтенький Unit test файл под именем Test.php в ./dockrant/share папке

Test.php

<?php  class Test extends PHPUnit_Framework_TestCase {     public function testSomething()     {         $this->assertTrue(true);     } } 

Настроим конфигурацию запуска

Запускаем Unit test

Также можно запустить Unit test с дебаггером

Теперь настроим плагин Docker Integration, после установки плагина необходимо добавить нашу машину в настройках Build, Execution, Deployment → Docker как правило папки docker-machines лежат в вашей домашней директории текущего пользователя, нам нужен sandbox docker-machine который мы создавали по инструкции вверху используя generic драйвер

Внизу вкладка Docker будет показана после перезагрузки IDE

Итог

Мы имеем окружение с полным набором необходимых сервисов и утилит разворачиваемое на большинстве операционных систем.

Развертывание окружения было протестировано на:

  • Windows 10
  • MacOS Sierra 10.12
  • Ubuntu 14.04 Desktop

Спасибо за прочтение, надеюсь эта статья поможет вам организовать удобное окружение.
ссылка на оригинал статьи https://habrahabr.ru/post/314032/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *