Gerenciamento de ambiente com Docker

DCOKER

Sejam bem vindos! Neste post vamos abordar a nossa experiência com o Docker no gerenciamento de ambientes de desenvolvimento, demonstrando alguns comandos e um breve passo a passo. Não vamos abordar a instalação do Docker, para isso acesse este post. Também não vamos abordar o Docker composer.

O problema:

A equipe de desenvolvimento back-end já tinha como tarefa dar manutenção em diversas aplicações que foram desenvolvidas utilizando o PHP na versão 5.4 em conjunto com o micro framework Slim na versão 2.0. Porém, no final do ano de 2016 foi acordado que todos os novos projetos deveriam ser desenvolvidos utilizando o PHP já na versão 7.1 e o Slim na versão 3.0. E agora, como sustentar um ambiente com as novas versões e ainda sim continuar as tarefas de manutenção e melhorias nos projetos com o ambiente obsoleto?

A solução:

Poderíamos utilizar o Vagrant, que é uma forma de manter ambientes virtuais. Porém, é muito pesado para o que precisávamos e em alguns momentos pesado demais para alguns dos hardwares utilizados pelos desenvolvedores. Então, a opção mais viável e interessante era o uso do Docker, que segundo seu próprio site, é uma abstração que adiciona recursos e simplifica o uso dos Linux Containers (LXC), que são uma forma de isolamento de processos e sistemas, o que pode ser entendido como um tipo virtualização, porém, mais leve e integrada ao kernel do Linux.

Por onde começar?

Estudando o Docker, decidimos que a melhor abordagem seria criar duas imagens, uma com o Ubuntu 14.04 configurada para o PHP 5.4 e outra com o Ubuntu 16.04 configurada para o PHP 7.1. Também decidimos que o ideal seria ter um container para cada projeto, sendo que cada container seria montado com a imagem correspondente. Perfeito, agora vamos colocar a mão na massa!

Mãos a obra:

Como o nosso objetivo envolvia criar imagens personalizadas, o caminho era utilizar o Dockerfile. Para isso, criamos um diretório com a seguinte estrutura:

/PHP5.6-ubuntu14.04
/PHP5.6-ubuntu14.04/apache-config.conf
/PHP5.6-ubuntu14.04/Dockerfile
Após criar a estrutura, começamos a escrever o Dockerfile, que ficou assim:

FROM ubuntu:14.04
MAINTAINER Pluritech Brasil LTDA <desenvolvimento@pluritech.com.br>
# Instalando os recursos para nosso ambiente.
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install curl apache2 php5 php5-curl php5-gd php5-mcrypt php5-pgsql
# Habilitando os mods do apache.
RUN a2enmod php5
RUN a2enmod rewrite
# Setando as variaveis do apache
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data
ENV APACHE_LOG_DIR /var/log/apache2
ENV APACHE_LOCK_DIR /var/lock/apache2
ENV APACHE_PID_FILE /var/run/apache2.pid
# Expondo o apache
EXPOSE 80
# Atualizando o .conf com a nossa configuração
ADD apache-config.conf /etc/apache2/sites-enabled/000-default.conf
# Mantendo o apache in the foreground, override with /bin/bash for interative.
CMD /usr/sbin/apache2ctl -D FOREGROUND
# Iniciando o apache assim que o container for iniciado.
ENTRYPOINT service apache2 start && /bin/bash

Por fim escrevemos o apache-config.conf de acordo com as nossas necessidades e ele ficou assim:

<VirtualHost *:80>
ServerAdmin guilherme@pluritech.com.br
DocumentRoot /var/www/site/public
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/site/public>
Options FollowSymLinks
AllowOverride All
Order deny,allow
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Após criar os arquivos dentro da estrutura, basta rodar o comando “build” para criar a imagem (lembre-se de estar dentro do diretório do Dockerfile para executar o comando). O comando tem a seguinte estrutura docker build -t nome_imagem:versao. Sendo assim o comando ficaria algo como: docker build -t pluritech/php5.6-ubuntu14.04:1.0. . O ponto no final é o parâmetro de localização do arquivo Dockerfile e ele direciona para o diretório atual. Após realizar o comando, todo o processo de construção da imagem será executado. Isso pode demorar alguns segundos e, no final, uma mensagem de sucesso será exibida. Para verificar a criação da imagem, basta executar o comando docker images e todas as imagens serão listadas. Para excluir uma imagem, basta usar o comando docker rmi -f image_id.

Agora que a imagem já estava criada, precisávamos subir o nosso container para prover o ambiente ao desenvolvedor. Para isso bastava utilizar o comando docker run -i -t -v patch_local:patch_destino nome_imagem:versao /bin/bash. Assim o comando ficaria algo como: docker run -i -t -v /home/user/public_html/projeto1/:/var/www/site pluritech/php5.6-ubuntu14.04:1.0 /bin/bash., sendo que o parametro -v com o patch local e destino, serve para espelhar o projeto da máquina root no container, o que permite que o desenvolvedor edite o projeto e as alterações sejam refletidas no container. Assim que o container é criado, você é direcionado para dentro dele, o que pode ser verificado pelo root@xdsaxsax à esquerda no terminal. Isso aconteceu graças ao parâmetro /bin/bash no final do comando run. Aproveite que está dentro do container e verifique se o apache está rodando através do comando ps -ef. Aproveite também para verificar o IP do container através do comando ifconfig. Deve ser algo parecido com 172.17.0.2. Por fim, para sair do container sem matá-lo, aperte ctrl + p + q. Para gerenciar os containers, alguns comandos úteis são:

Listar todos os containers docker ps.
Acessar um container docker attach container_id.
Excluir um container docker rm -f container_id.
Parar um container docker stop container_id.
Iniciar um container docker start container_id.
Após ter o container rodando, configuramos o arquivo hosts da máquina root de forma que o container fosse acessado por um endereço amigável. Para isso, edite o arquivo /etc/hosts com seu editor preferido e adicione a linha com o endereco_container endereco_amigavel, que deve ficar algo como: 172.17.0.2 meuprojeto-sandbox. Neste ponto, ao digitar o endereço meuprojeto-sandbox no seu navegador, o arquivo index que esta em public do seu projeto deve ser exibido.

E, por fim, bastava configurar o acesso ao banco de dados que o projeto dentro do container teria que fazer. Para isso, poderíamos criar um container para prover o banco de dados ou permitir o acesso externo ao banco configurado na máquina root. No nosso caso, escolhemos a segunda opção. Sendo assim, nosso container apontava para o IP da máquina root que permitia o acesso externo.

Por fim, bastava fazer o mesmo processo para o PHP 7.1 e assim teríamos dois containers onde cada um estaria provendo um ambiente diferente para o desenvolvedor. No inicio pode parecer algo complexo mas é realmente simples gerenciar o ambiente com o Docker. E isso é apenas o inicio. Com o docker composer você pode especificar todas as configurações do seu ambiente de desenvolvimento e subir o ambiente em uma nova máquina em segundos. Sem falar na escalabilidade em ambientes de produção, mas isso é assunto para um próximo post.