📜 ⬆️ ⬇️

Setting up the environment for PHP developers

In this article we will look at setting up the environment for PHP developers using Vagrant , Docker , Xdebug , PHPUnit , and integration with IDE PHPStorm .

+

Requirements




Training


We will not focus on installing the necessary tools for certain operating systems, installation instructions are on the official websites, links are attached.
')

What is included in the assembly?



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

Setup and Configuration


Attention! All described settings and files are uploaded to GitHub . If you have any questions about using Vagrant or Docker, refer to the official documentation.

The deployment of the environment is slightly different on different operating systems:


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 

The guest OS will work on Ubuntu 14.04 (Trusty) , the static IP address is 10.0.0.2 and we will use NFS mount as the share folder.

For convenience, create a folder called dockrant (Docker + Vagrant = Dockrant), later in the article we will build on this folder.

Determine the folder structure:

./dockrant is our root folder
./dockrant/ssh - SSH keys for guest OS (in this tutorial we use standard vagrant keys)
./dockrant/share - share-folder between the host and guest OS
./dockrant/share/tools - folder with our tools and bash scripts
./dockrant/vagrant/build - executable bash scripts when raising the guest OS

Now we need to put all the necessary scripts and instructions for the folder structure described above, let's go through the list.

./dockrant/ssh - we put two files id_rsa (private key) and id_rsa.pub (public key)

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/ - we will create a phpinfo.php file with the phpinfo () function, so that we can check the performance

phpinfo.php
 <?php phpinfo(); 

./dockrant/share/tools/ - put a few helper scripts to run PHP interpreters from under Docker exec and PHPUnit (download from 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" 

For php * scripts, we do not use TTY, these scripts are needed to correctly configure integration with the IDE in using remote interpreters, php * tty scripts are needed to manually use the launch of PHP scripts, including in the interactive mode php -a .

./dockrant/vagrant/build/php/ - we put the init.sh bash script to copy executable files running PHP interpreters.

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/ - we put init.sh and docker-compose.sh bash scripts to install docker-compose and container assembly commands when raising the guest OS.

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


Create the file ./dockrant/share/docker-compose.yml

Now we will describe the instructions for creating docker containers, we will not describe the instructions for assembling each image, we will take ready.

We collect from the following images:


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


Create a Vagrantfile file in the dockrant folder and write the following instructions there

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 


Tuning:


Launch


In the dockrant folder , run the command

 vagrant up --provider virtualbox 

After assembly, open in the browser - sandbox.local / phpinfo.php


Docker-machine


In order for our virtual machine to work as a docker-machine, we need to add it using the generic driver, run from the dockrant folder

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

After creating the docker-machine , the guest machine needs to be rebooted, because after installation all docker containers stop

 vagrant reload 

PHP CLI


PHP scripts are run on the guest machine ( 10.0.0.2 ), remember that there is a / share folder between the host machine and the guest one.

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

Running PHP interpreters online

 php56tty -a php70tty -a 

PHPStorm Integration


We set up a debugger using XDebug , screw PHPUnit and add management of our containers through the Docker Integration plugin, with which you can view the logs of our services, reload containers, execute scripts.

Add our PHP interpreters to the settings, open the Settings Languages ​​& Frameworks → PHP settings



We first add version 5.6, then repeat for version 7.0, click on the button ...

Then clicking on + select Remote ...



In the pop-up window, select the Vagrant type and specify the path to the PHP interpreter on the guest OS / usr / bin / php56




Now we will add our remote server to the list for working with the debugger on request from the browser
Language & Frameworks → PHP → Servers . Let's assign the path mappings to our / share folder so that the IDE can recognize requests for paths between the host machine and the guest.



Set up PHPUnit , go to Language & Frameworks → PHP → PHPUnit settings and for each PHP version of the interpreter, write the path to /share/tools/phpunit.phar





We are almost ready to debug our application, but we still have to configure launch configurations.


Configure PHP Remote Debug





Put a breakpoint for example in the phpinfo.php file on line 2, launch the debugger, go to the sandbox.local / phpinfo.php page in the browser and see that our debugger worked in the IDE







Now for PHPUnit


Create a simple Unit test file called Test.php in the ./dockrant/share folder

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

Configure launch configuration



Run unit test





You can also run Unit test with debugger





Now we will configure the Docker Integration plugin, after installing the plugin, we need to add our machine in the Build, Execution, Deployment → Docker settings , as a rule, the docker-machines folders are in your home directory of the current user, we need a sandbox docker-machine that we created according to the instructions above using generic driver



Below the Docker tab will be shown after restarting the IDE.



Total


We have an environment with a full set of necessary services and utilities deployed on most operating systems.

The deployment of the environment was tested on:


Thanks for reading, I hope this article will help you organize a comfortable environment.

Source: https://habr.com/ru/post/314032/


All Articles