Eu liberei uma imagem Docker voltada para desenvolvimento PHP com as últimas versões suportadas do PHP instaladas mais a última versão do PHP 5.3. O objetivo da imagem é ajudar desenvolvedores que precisam desenvolver e testar seus projetos em diferentes versões do PHP (especialmente desenvolvedores de softwares livres ou de código aberto).

Docker é uma ferramenta construída em cima das funcionalidades de virtualização de nível de sistema operacional do Linux. Permite que aplicações sejam construídas e entregues como containers (contêineres), o que pode significar que você pode usá-lo no seu deployment pipeline para gerar um container Docker como seu binário entregável (se adotar Docker tanto para desenvolvimento como para produção) ou apenas usá-lo para propósitos de desenvolvimento como uma reposição ao Vagrant, por exemplo. Eu não vou me estender nesse assunto, leia o Docker User Guide e este parágrafo irá ficar muito mais claro, acredite!

Usando a imagem Docker

Agora que você está acostumado com o Docker e o instalou, usar a imagem PHP Development será bem simples. Na data de publicação desta, as seguintes versões do PHP estão disponíveis:

  • 5.6.3
  • 5.5.19
  • 5.4.35
  • 5.3.29

Cada versão do PHP vem com as extensões Zend OPCache e Xdebug instaladas e algumas ferramentas de QA para PHP estão instaladas globalmente com o Composer. A imagem também possui o Nginx e PHP-FPM instalados. Veja a página da imagem para uma lista completa das extensões e bibliotecas instaladas.

Vamos iniciar um novo container. Primeiro, faça o download da imagem do Docker Hub:

$ docker pull eriksencosta/php-dev

Agora, vamos criar uma aplicação “Hello World” muito simples:

$ mkdir ~/hello-world; echo '<?php echo "Hello world!";' > ~/hello-world/index.php

Inicie o container:

$ docker run -p 80:80 -v ~/hello-world:/var/www/hello-world -d "eriksencosta/php-dev:latest"

Abra o endereço http://localhost/hello-world/ (se estiver usando o Boot2Docker, substitua localhost com o endereço de IP retornado pelo comando boot2docker ip) no seu navegador e se delicie com a sua incrível aplicação cumprimentando o mundo inteiro. Melhor que a ONU, dizem.

Se você acessar o endereço http://localhost/info.php, você verá a informação completa da versão do PHP em execução.

Trocando entre as versões do PHP

Para ver o valor real da imagem, você precisa trocar entre versões PHP. Pare o container atual em execução:

$ docker stop $(docker ps -l | tail -1 | awk '{print $1}')

E inicie um novo container em modo interativo:

$ docker run -t -i -p 80:80 -v ~/hello-world:/var/www/hello-world "eriksencosta/php-dev:latest" /bin/bash

Você será atribuído a um terminal no container. Para trocar entre diferentes versões do PHP, use o comando phpenv:

# 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 e 5.3 são apenas atalhos. O phpenv permite que você defina as versões globais (pro sistema) e locais do PHP. Para determinar globalmente:

# 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

Para determinar uma versão local, execute:

# 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

Para iniciar o Nginx e o PHP-FPM, execute:

# webserver start
Starting PHP-FPM (PHP version 5.3) server.
Starting Nginx server.
Done.

Para desabilitar o Zend OPCache (é habilitado por padrão):

# 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

Um exemplo da vida real

Não há nada de errado com a nossa aplicação “Hello World” mas… ela não faz nada! Então vamos ver um exemplo melhor usando uma aplicação Silex bem simples. Esta aplicação exemplo é um issue tracker que apenas lista as issues (que estão armazenadas em um banco de dados MySQL). Faça um clone do repositório da aplicação:

$ cd ~
$ git clone git://github.com/eriksencosta/silex-docker-example.git

Nossa aplicação precisa de um banco de dados MySQL. Mas nosso container PHP não vem com um servidor MySQL. O poder do Docker está no uso de imagens leves como blocos de construção. Então, ao invés de criar uma imagem com todas as dependências da aplicação, você inicia diferentes containers Docker e os consome como recursos anexados de rede. Com isto em mente, faça o download da imagem Docker do MySQL:

$ docker pull mysql

Inicie o container MySQL:

$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=root -d mysql

Inicie o container PHP:

$ 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

Execute os comandos de preparação e configuração necessários:

# 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

Para verificar que tudo está funcionando, execute a suíte de testes:

# behat

Carregue as fixtures no banco de dados:

# php app/console example:fixtures:load --truncate

Configure o virtual host Nginx e inicie os servidores:

# cp dockerfiles/php-dev/default.vhost /etc/nginx/sites-available/default
# webserver start

No seu navegador, acesse http://localhost. Isso é tudo!

Concluindo

Eu limitei o escopo deste post para apresentar a você a imagem Docker e não para explicar totalmente o que é o Docker e como usá-lo mas, espero que eu tenha despertado o interesse em você.

Esta imagem Docker é voltada apenas para propósitos de desenvolvimento (não é para ser usada em produção!). A imagem é construída usando o playbook Ansible PHP Development. O Dockerfile também está no GitHub. O README da aplicação de exemplo em Silex tem um exemplo de uso extra.