A Docker image for multi-version PHP development
I released a Docker image suitable for PHP development with the latest supported PHP versions installled plus latest 5.3 release. The image is aimed to help developers which need to develop and test their projects in different PHP versions (specially free or open source software developers).
Docker is a tool built on top of Linux’s operating system-level virtualization features. It allows applications to be build and shipped as containers, which can mean that you can hook it in your deployment pipeline to generate a Docker container as your shippable binary (if adopting Docker for both development and production) or just use it for development purposes as a replacement to Vagrant, for example. I won’t extend on this, read the Docker user guide and this paragraph will be a lot clearer, believe me!
Using the Docker image
Now that you’re used to Docker and installed it, using the PHP Development image will be straightforward. At the time of writing, it comes with the following PHP versions:
- 5.6.3
- 5.5.19
- 5.4.35
- 5.3.29
Each PHP version comes with the Zend OPCache and Xdebug extensions installed and some PHP QA tools are installed globally with Composer. The image also ships with Nginx and PHP-FPM. Check the image’s page for a full list of the extensions and libraries installed.
Let’s start a new container. First, pull the image from the Docker Hub:
$ docker pull eriksencosta/php-dev
Now, let’s create a very simple “Hello World” application:
$ mkdir ~/hello-world; echo '<?php echo "Hello world!";' > ~/hello-world/index.php
Start up the container:
$ docker run -p 80:80 -v ~/hello-world:/var/www/hello-world -d "eriksencosta/php-dev:latest"
Open http://localhost/hello-world/
(if you’re using Boot2Docker, replace localhost
with the IP address returned from the command boot2docker ip
) in your browser and be delighted by your awesome application greeting the whole world. Better than the UN, they say.
If you go to http://localhost/info.php
, you’ll see the full information from the running PHP version.
Switching between the PHP versions
To get the real value of the image, you need to switch between the PHP versions. Stop the current running container:
$ docker stop $(docker ps -l | tail -1 | awk '{print $1}')
And start a new container in interactive mode:
$ docker run -t -i -p 80:80 -v ~/hello-world:/var/www/hello-world "eriksencosta/php-dev:latest" /bin/bash
You’ll be assigned with a terminal inside the container. To switch between the different PHP versions, use the phpenv
command:
# phpenv versions
5.3
5.3.29
5.4
5.4.35
5.5
5.5.19
5.6
* 5.6.3 (set by /opt/phpenv/version)
5.6, 5.5, 5.4 and 5.3 are just shortcuts. phpenv let you define the global (system-wide) and local PHP version. To set it globally:
# phpenv global 5.4
# php -v
PHP 5.4.35 (cli) (built: Dec 14 2014 00:35:12)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.6, Copyright (c) 2002-2014, by Derick Rethans
To set a local version, run:
# cd /var/www/hello-world
# phpenv local 5.3
# php -v
PHP 5.3.29 (cli) (built: Dec 14 2014 00:24:19)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.6, Copyright (c) 2002-2014, by Derick Rethans
To start Nginx and PHP-FPM, run:
# webserver start
Starting PHP-FPM (PHP version 5.3) server.
Starting Nginx server.
Done.
To disable the Zend OPCache (which is enabled by default):
# opcache disable
The Zend OPCache (PHP version 5.3) was disabled.
You need to restart the webserver for the changes to take effect.
Execute: webserver restart
A real life example
There is nothing wrong with the “Hello World” application but… it does nothing! So let’s move to a better example using a simple Silex application. This example application is an issue tracker that only list issues (that are stored in a MySQL database). Clone the application’s repository:
$ cd ~
$ git clone git://github.com/eriksencosta/silex-docker-example.git
Our application needs a MySQL database. But our PHP container don’t comes with a MySQL server. The power of Docker lies in using lightweight images as building blocks. So instead of creating an image with all application dependencies, you start different Docker containers and consume then as attached network resources. With this in mind, pull the MySQL Docker image:
$ docker pull mysql
Start the MySQL container:
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=root -d mysql
Start the PHP container:
$ docker run -t -i --link some-mysql:mysql -p 80:80 -v ~/silex-docker-example:/var/www/example -P "eriksencosta/php-dev:latest" /bin/bash
Run the needed set up commands:
# cd /var/www/example
# composer install
# php app/console example:configure:environment --variable="EXAMPLE_DEBUG=true"
# php app/console example:database:create
# php app/console example:schema:create
To check everything is working, run the test suite:
# behat
Load the fixtures data to the database:
# php app/console example:fixtures:load --truncate
Configure the Nginx virtual host and start the servers:
# cp dockerfiles/php-dev/default.vhost /etc/nginx/sites-available/default
# webserver start
In your browser, go to http://localhost
. That’s all!
Wrapping up
I limited the scope of this post to present the Docker image and not to explain fully what is Docker and how to use it but I hope I’ve raised some interest about it on you.
This Docker image is intended only for development purposes (it is not meant to be used in production!). The image is built using the PHP Development Ansible playbook. The Dockerfile is on GitHub too. The Silex example application README have an extra usage example.
This post is available in Brazilian Portuguese too!
Want to discuss this post? Reach me at Twitter!