PHP Vagrant box

Posted by Twisted Bytes on 15 December 2015

 At Twisted Bytes we talk a lot about making live easier for developers. We do that by creating excellent servers that do what they should do without so developers can keep focused on the code. But code needs to be programmed. And that is done with a local development environment like a LAMP-stack or a Vagrant box. With this blog we make our Vagrant box public.

We created one to make the development environment almost equal to the servers we deliver to our customers. And that will reduce the surprises when your code goes to one of our servers. We added some tools to make development and debugging easier: xdebug, xhprof en mailcatcher. 

 

Vagrant introduction

We don’t want to spend too much time on explaining Vagrant itself. There is a lot of information about it to find in the internet. To point you in the right direction start here: the site of vagrant, https://www.vagrantup.com/. Next one is: “getting started” and “Why Vagrant”.

Vagrant is a tool to use configure images of virtual machines so they can be used for developing code. You can compare it to a local installation of PHP, MySQL/MariaDB and Apache. The difference is that you do not have to install or configure anything except one file per project and Vagrant on your computer. After this the file can be used by you and your colleagues to get the same environment on another computer. No more installing LAMP stacks and finding our which PHP to install. It’s all defined by one simple file. And with that file you can start a fully configured virtual machine with everything you need to do PHP web development.

Vagrant is so nice to work with because it has the option to share directories from your computer with the virtual machine. That way you keep the development files local while the Vagrant environment can use them to serve them through PHP and Apache.

Vagrant needs 2 parts: the Vagrant installation and a virtual machine runner. VirtualBox is in general the virtual machine runner. To use Vagrant you have to install both. To install VirtualBox go to: https://www.virtualbox.org/wiki/Downloads. To install Vagrant go to: https://www.vagrantup.com/downloads.html.

 

Installation and usage

There are lots and lots of Vagrant boxes to be found all over the internet. But those are not equal to how we setup our servers. And when you use those you can get surprises when code does something else on the server compared to what locally did.

That’s why we created our web development Vagrant box. The running Linux, Apache Mariadb and PHP software and configuration are equal what you can expect on our servers. The directory structure is as explained in our previous blog.

To use our box is easy. Create a project and place a “Vagrantfile” in the base directory of the project. Go to that directory and run “vagrant up”. The image is downloaded and the virtual machine booted right after that.

The Vagrantfile for our box is this one:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
   config.vm.box = "twistedbytes/webserver"

   config.vm.network "private_network", ip: "192.168.50.100"
   # Create a forwarded port mapping which allows access to a specific port
   config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: '127.0.0.1', auto_correct: true
   config.vm.network "forwarded_port", guest: 3306, host: 3306, host_ip: '127.0.0.1', auto_correct: true
   # for mailcatcher
   config.vm.network "forwarded_port", guest: 1080, host: 1080, host_ip: '127.0.0.1', auto_correct: true

   config.vm.synced_folder "docroot",         "/data/site/docroot",   create: true, owner: 'defaultsite', group: 'defaultsite'
   config.vm.synced_folder "other/logs",      "/data/logs",           create: true, owner: 'defaultsite', group: 'defaultsite'
   config.vm.synced_folder "other/private",   "/data/private",        create: true, owner: 'defaultsite', group: 'defaultsite'

   config.vm.provision "shell", run: 'always', inline: <<SCRIPT
       /usr/local/bin/autorun.sh
       # systemctl restart mysql
SCRIPT

end

A short explanation of the file:

  • de config.vm.box The name of the box.
  • config.vm.network. The network the box is active on. This should be 192.168.50.X, but no 192.168.50.1. Your computer will be 192.168.50.1 and xdebug will try to connect to, for example, PHPStorm of Eclipse.
    • The local site is also available on that chosen IP. In this case: http://192.168.50.100/.
    • When running multiple vagrant boxen be sure to change this IP. You cannot have multiple boxes active on the same IP.
  • The forwarded ports to localhost. 80 3306 and 1080. This means that those ports are connected to your localhost. For port 80 of the virtual machine: http://localhost:8080/.
    • The ports 3306 and 1080 are for MariaDB and Mailcatcher: http://localhost:1080/.
    • When starting multiple boxes and ports overlap they will be moved to some other port. Please check the output when starting a box.
  • The synced_folders. These lines map the local directories to a somewhere in the virtual machine. This configuration expects a directory named “docroot”. Later more about it.
    • The 2 other synced_folders, logs and private, are there to get 2 directories from the virtual machine into your project. These contain the logfiles and private directory. They are here to make it easy to view those without the need to login into the box.
  • The last part is the provision script. This runs every time the box starts with “up” and “reload”. This executes some scripts setup some things in the box and the shared_folders.

 

Directory structure

In a previous blog we explained our directory structure on the servers. This Vagrant box uses a some structure. The only change is that it is not placed at /var/www/vhost/TBXX-XXX/<sitename> but at /data. This was done to keep the configuration easy on this single-purpose box.

Each site has a “docroot” directory. It is the root directory of your site. We named it “docroot”. You can change the name but you have to update the Vagrantfile, use “.” for the directory where the Vagrantfile is placed or “public” if it is name “public”. Add more shared_folder statements when you have more directories to share with the box.

This is what the directory structure will look like when started:

/data
├── logs
│   ├── php
│   │   └── php-slow.log
│   │   └── php-error.log
│   └── web
│       ├── httpd_access.log
│       └── httpd_error.log
├── private
│   ├── php-append.php
│   ├── php-prepend.php
│   ├── databases.ini
│   ├── php-sessions
│   └── php-tmp
├── site
│   └── docroot


Installed software and functions

The Vagrant box can run a PHP site. But because it is a development box we added some extra options that make life easier. By default these things are present:

  • PhpMyAdmin: http://localhost:8080/pma/
  • composer installation at: /usr/local/bin/composer
  • wp-cli installation at: /usr/local/bin/wp
  • sassc installation at: /usr/local/bin/sassc
  • PHP version 5.6 and PHP 7.0

And some other things that need extra explanation.

 

PHP5 en PHP7 switch

PHP7 has been released and we added it to our box. It’s not used by default but we made and option to switch between them without restarting anything. This makes it easy to use or test PHP7.

To switch between PHP5 and PHP7 you have to run a command in the Vagrant box. Let's show that to you:

# open a terminal and go the the project directory where the Vagrantfile is placed:

> vagrant ssh

> sudo su # to become root
> /usr/local/bin/php-version-switcher.sh defaultsite 5 # to use php 5
> /usr/local/bin/php-version-switcher.sh defaultsite 7 # to use php 7

If you want this functionality on your server, please contact us.

 

Mailcatcher

Mailcatcher is a tool to catch mail that normally would be send out a real email address. Because you probably do not want that in your development environment, but you do want to test sending email mailcatcher catches those mails. So you can view them and not bother your clients or users. Check the site for more information: http://mailcatcher.me/.

We added this to our box because it is a great development tool that helps to solve a common problem. Simon, thanks for the suggestion!

Mailcatcher is available at http://localhost:1080/ or at http://192.168.50.XX:1080/

 

Xdebug

Xdebug is the standard method to debug PHP code. It is not easy or fun to set it up so we did it so you can just use it with your favorite IDE.

We tested it with PHPStorm and Eclipse. It is important to have the IDE running on a computer with the IP 192.168.50.1. This is done when the Vagrantfile contains the line ‘config.vm.network "private_network", ip: "192.168.50.100"’. You can change the number 100 into anything but 1 and 255 to have multiple boxes running in parallel.

To use xdebug we just link to sites that explain it. To use xdebug you need 2 things. A browser plugin to enable xdebug for this request and a program to receive the debug information. When enabled it starts a debug session and contact this port: 192.168.50.1:9000. You need to configure your IDE to listen to it. Check out these urls to set this up.

 

XHprof

XHprof is another tool that could help you making better PHP code. It is a profiler. And we made it easy to use.

But why use a profiler? It helps you figure out why your code is slow or using a lot of memory. A profiler collects statistics while running and presents you with an overview of the runtime and memory usage of all functions it needed to call. This helps to pinpoint a problem without the need for some long debugging session. More to read about xhprof and profiling:

You do not need to install or configure anything they talk about in that blog. We already did that.  The only thing you need to do is edit the file php-prepend and php-append in the ~private/ directory to use one of the 2 gui’s we installed in the box: xhprof and xhprof.io.

To use them go to:

 

Other functionality

To finish this blog we explain some standard tools we installed in the server and how to use them.

PhpMyAdmin is installed and can be reached at: http://localhost:8080/pma. Login with root without password. Or use the default database user: “defaultsite” with the password being the same as the username. 

To connect to MariaDB with a desktop client use localhost 3306 or vagrantIP:3306.

PHP without composer is almost impossible. So to use it, login to vagrant and become the user of the website with the command “sudef”:

> vagrant ssh
Last login: Sun Nov 29 12:26:35 2015 from 10.0.2.2
Welcome to your Vagrant-built virtual machine.

Use command "sudef" te become user defaultsite, to use composer and other commandline tools

[vagrant@localhost ~]$ sudef
defaultsite@localhost /data> cd site/docroot/
defaultsite@localhost /data/site/docroot> composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Nothing to install or update
Generating autoload files
defaultsite@localhost /data/site/docroot>

We also installed WP-cli. It is a cli tool for wordpress tasks. see: http://wp-cli.org/. Use it the same way as composer. Login to the box and use “sudef” te su to the website's user. Run “wp” or “wpcli”.

 

Conclusion

We hope this makes developing PHP easier. If you have any question, remarks or suggestions, please do not hesitate to contact us. We really enjoy people using this box and sending us feedback!

config.vm.network. The network the box is active on. This should be 192.168.50.X, but no 192.168.50.1. Your computer will be 192.168.50.1 and xdebug will try to connect to, for example, PHPStorm of Eclipse.