Para garantir a padronização das aplicações e facilitar o trabalho do dia a dia, na Convenia, utilizamos uma imagem base para todas as aplicações. O proposito desse post é mostrar as vantagens dessa abordagem e como criar suas aplicações a partir dessa imagem.
Porque padronizar a imagem base?
Na Convenia temos uma stack bem homogênea quase que inteiramente em PHP, manter uma imagem diferente em cada projeto aumenta a chance de aparecer um problema específico com uma versão específica de uma biblioteca que está instalada apenas em um projeto, o desenvolvedor que mantém esse projeto terá que resolver esse problema e não terá como reaproveitar o conhecimento dos amigos visto que esse problema ocorreu apenas no projeto dele.
Seguindo a mesma linha de raciocínio imagine o quão diferente os setups podem parecer sem uma padronização, manter essa padronização ajuda bastante quando o desenvolvedor muda de projeto ou mesmo quando ele faz um “merge request” em um outro projeto, dessa forma ganhamos agilidade por não ter que estudar especificidades de cada projeto.
Novas features e correções de bugs são centralizadas em apenas uma imagem ao invés de serem feitas em cada projeto.
Bom e finalmente eliminamos o famoso “na minha maquina funciona”. Já que estamos utilizando um container padronizado no ambiente de desenvolvimento porque não utilizar o mesmo container em ambiente de produção(com alguns cuidados claro)? Isso praticamente erradica a possibilidade de ocorrer um erro proveniente da discrepância entre uma biblioteca visto que quase todas as bibliotecas vão ser idênticas. Esse risco só não é nulo porque inevitavelmente vamos ter que instalar alguma extensão antes de enviar para produção(opcache por exemplo).
Em algum momento teremos que gerar uma nova imagem a partir da imagem base contendo a aplicação para rodar em produção. Se todos os projetos tem a necessidade de ter um webserver por exemplo porque não adicionar esse webserver já na imagem base? Isso vai tornar a etapa de build do pipeline muito mais rápida visto que passamos a maioria das coisas comuns aos projetos para a imagem base, temos um deploy mais ágil!
Utilizando a imagem base
Para rodar uma aplicações PHP da forma convencional são necessários 2 containers, o PHP-FPM e um servidor web como nginx ou apache. Rodar esses 2 componentes separadamente, apesar de ser o recomendado, demanda que o desenvolvedor mergulhe em detalhes referentes à comunicação entre os containers e até mesmo configuração de volumes, muitas vezes esses detalhes não são interessantes no momento, desenvolvedores iniciantes se sentem bem perdidos nesses detalhes.
Analisando outras stacks como nodejs vamos perceber que é relativamente mais simples containerizar esse tipo de aplicação, pois o próprio processo do node já é capaz de servir os requests sendo necessário apenas um container, mas e se podessemos rodar uma aplicação PHP com a mesma simplicidade? Essa é a proposta da imagem PHP Full que utilizamos aqui na convenia como imagem base de todas as aplicações PHP.
Vamos executar a imagem PHP Full com o seguinte comando:
docker run --rm -p 80:80 convenia/php-full:latest
convenia/php-full:latest
e binda a porta 80 do container à porta 80 do host, logo ao entrar no nosso localhost pelo browser(em windows e macOS pode ser necessário utilizar o IP da vm do docker, dependendo do seu setup) devemos ver a página da documentação:Essa documentação é um arquivo PHP, isso significa que a imagem já está pronta para servir nossa aplicação, tudo que precisamos fazer é colocar nossa aplicação dentro do diretório /var/www/app
que é onde a imagem procura por padrão.
Para fazer um lab bem rápido vamos executar um comando no terminal para instalar uma aplicação Laravel fresh:
docker run --user 1000 --rm -v $(pwd):/app composer create-project laravel/laravel
/var/www/app
, é nessa pasta que o webserver dentro do container olha para servir a aplicação:docker run --rm -p 80:80 -v $(pwd)/laravel:/var/www/app convenia/php-full:latest
Pronto finalmente estamos rodando nossa aplicação PHP dentro do container, e tudo que fizemos foi copiar a aplicação para uma pasta específica dentro do container, esse é o propósito dessa imagem, prover uma forma simples e segura para executar aplicações PHP podendo ser utilizado em ambiente de desenvolvimento e produção.
Criando um arquivo Docker Compose
Já sabemos como utilizar nossa imagem porém em um ambiente real podemos sentir a necessidade de rodar mais de um container, containers de serviços como mysql e redis para nossa aplicação e o próprio container da nossa aplicação pode começar a ficar complexo pois pode surgir a necessidade de utilizar mais volumes, podemos definir uma network para isolar nossa aplicação. Logo o comando para rodar esse container vai ficando cada vez mais complexo e rodar a stack completa se torna uma tarefa árdua. Para resolver esse problema utilizamos um arquivo docker-compose.yml
que deve ser criado na raiz do projeto:
version: '3.3'
services:
app:
image: convenia/php-full:latest
container_name: application
volumes:
- .:/var/www/app
ports:
- 80:80
docker-compose up -d
Conclusão
Com certeza padronizar uma imagem base nos seus projetos não vai resolver todos os seus problemas mas ajuda a diminuir a complexidade na implantação e evita silos de conhecimento relacionados ao setup local, espero ter contribuído com esse post, deixe sua opinião nos comentários ou me da um grito no twitter.