Oi, pessoal!
A intenção hoje é trazer para vocês um conteúdo mais voltado para as equipes de desenvolvimento, ilustrando como é possível automatizar alguns pontos do seu trabalho utilizando Docker e como ele tornará as equipes mais eficientes naquilo que precisam ser: entrega de resultado, óbvio.
Neste exemplo, abordaremos um pouco sobre como é fácil montar um ambiente de desenvolvimento local utilizando nginx, php e mysql. Este será, é claro, o primeiro passo em seu caminho para utilizar Docker no seu dia-a-dia.
Obviamente, nesse artigo não abordaremos como você deve instalar o Docker; para isso temos esse artigo que vai lhe ajudar muito. Veja também que vamos usar nesse ambiente o docker compose, e claro, levamos em consideração que você está utilizando Docker em seu host de desenvolvimento, seja ele Windows, Linux ou Mac, e não no servidor de produção.
A receita
“Ok, atendo a esses requisitos. E agora Cristiano, o que faço?”. Primeiramente, você deve criar, dentro de seu diretório de trabalho, um arquivo para que o Docker Compose possa dar início a sua stack, e como você viu no artigo sobre o Docker Compose, o formato dele é de um arquivo do tipo Yaml. Vamos utilizar a versão 2 do Docker Compose, que trás algumas melhorias, mas que difere um pouco na sintaxe. Veja o exemplo que vamos usar:
# Utilizando sintaxe da versão 2: version: '2' volumes: database_data: driver: local services: ########################### # Container Web (Nginx) ########################### nginx: image: nginx:latest ports: - 8080:80 volumes: - ./nginx/default.conf:/etc/nginx/conf.d/default.conf volumes_from: - php ########################### # Container PHP ########################### php: build: ./php/ expose: - 9000 volumes: - .:/var/www/html ########################### # Container de banco de dados (MySQL) ########################### mysql: image: mysql:latest expose: - 3306 volumes: - database_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: senha MYSQL_DATABASE: projeto MYSQL_USER: projeto MYSQL_PASSWORD: projeto
A grande diferença entre a versão 1 e 2 do Docker Compose está relacionado a utilização de algumas tags especiais, entre elas: services e volumes. Essas tags obviamente foram adicionadas por um bom motivo, e esse motivo é você poder ter múltiplos serviços dentro de uma stack, mas ter a flexibilidade de escalonar ou modificar atributos de um único serviço dentro de sua stack, sem precisar mexer em toda ela. Isso é muito bom, não?!
Outro motivo está relacionado ao uso de volumes para a persistência de dados – você não quer perder todo seu trabalho se seu container for acidentalmente removido, certo? E uma das grandes vantagens nesse caso é que você pode especificar um driver para volume que seja persistente não apenas em seu host, mas distribuído em um cluster de volume (explicamos um pouco sobre isso aqui e aqui) e em nosso exemplo vamos usar local mesmo.
Inside
Note que nas linhas que se referem ao container PHP, não há referência para imagem. O motivo é simples: faremos o build da imagem no mesmo momento de subir a stack, ou seja, quando rodarmos o docker-compose up -d, o Docker realizará o build do Dockerfile que se encontra dentro da pasta PHP e utilizará a imagem gerada por esse build para iniciar o container php.
Mas e o que tem nesse Dockerfile? Calma, não íamos deixar isso de lado. Veja abaixo como é esse Dockerfile:
FROM php:7.0-fpm RUN docker-php-ext-install pdo_mysql \ && docker-php-ext-install json
Em nosso lab, usaremos como base a imagem do PHP 7.0 em fpm. Baseado nisso, instalaremos algumas extensões para que, posteriormente, possamos utilizá-las. Note que não é algo muito elaborado, mas poderia ser, caso você tenha essa necessidade. Na imagem em questão, há um binário responsável pela instalação das extensões, que é o docker-php-ext-install; ele realiza o download e instalação da extensão e sua ativação no php.ini global.
Note também que definimos expor a porta 9000 do container php para que o container do serviço web possa acessá-lo e, assim, processar as requisições. O arquivo de configuração do servidor web deve ser assim:
server { # Set the port to listen on and the server name listen 80 default_server; # Set the document root of the project root /var/www/html/public; # Set the directory index files index index.php; # Specify the default character set charset utf-8; # Setup the default location configuration location / { try_files $uri $uri/ /index.php; } # Specify the details of favicon.ico location = /favicon.ico { access_log off; log_not_found off; } # Specify the details of robots.txt location = /robots.txt { access_log off; log_not_found off; } # Specify the logging configuration access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; sendfile off; client_max_body_size 100m; # Specify what happens when PHP files are requested location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass php:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param APPLICATION_ENV development; fastcgi_intercept_errors off; fastcgi_buffer_size 16k; fastcgi_buffers 4 16k; } # Specify what happens what .ht files are requested location ~ /\.ht { deny all; } }
Veja que na opção: fastcgi_pass definimos como php:9000 ou seja, o nome do container na porta que expomos no docker-compose. Lembrando que você pode ter acesso a stack completa baixando esse exemplo de nosso repositório no Gitub.
Para o container de banco de dados, utilizamos a imagem oficial do MySQL, definimos apenas os dados de acesso e nome do banco de dados que gostaríamos de criar e, claro, definimos um volume onde serão persistidos os dados desse banco.
Agora basta você subir a sua stack, para isso: docker-compose up -d
Depois do Docker Compose realizar todo o processo de build da sua stack, basta você acessar o ambiente web pelo endereço: http://localhost:8080 e você terá como retorno a pagina inicial do seu site (que em nosso teste é apenas um phpinfo).
Próximos passos
Bom, agora você só precisar criar! Quando você criar alguma modificação na pasta onde está o projeto, elas serão refletidas no site, ou seja, modificando o seu index.php, será alterado no site que está rodando nos container, isso porque mapeamos a pasta local como sendo a public do servidor web/php. O mais interessante dessa abordagem é poder movimentar esse ambiente para onde quiser. Imagine que isso tudo faz parte de seu código versionado no git, basta chegar em basta e rodar um git clone do seu projeto (ou pull) e você terá o mesmo ambiente de desenvolvimento.
Gostou? Não gostou? Tem dúvida? Deixa nos comentários que vamos conversando!
Um grande abraço!