Trabalhando em ambientes PHP com Docker [Parte-1]

Sábado, dia 17/12/2016, ocorreu em Fortaleza o evento Darkmira Tour Community & PHP Com Rapadura. Um evento focado em fábrica de software, onde foram ministradas várias palestras com temas relacionados a Docker, JWT, REST API + TDD, Segurança eObject Calisthenics.

Durante o evento, tive a oportunidade de falar sobreDocker, uma tecnologia que mudou bastante a minha forma de trabalhar. Antes eu trabalhava em ambiente local; depois passei a usar o Vagrant, achando-o super lento, porém já achando muito útil a forma de trabalhar em um ambiente separado, mesmo que ainda sem muito sucesso… Até que conheci o Docker!

Antes de continuar, gostaria de lhe fazer duas perguntas:

Você já ouviu falar ou falou aquela velha frase: “Na minha máquina funciona”? Ou pior: “No servidor funciona”?

Pois é, meu amigo… Se você já ouviu alguém falar essas frases, ou se já falou uma delas, você precisa ler agora mesmo esse post, bem como a continuação dele, que será divulgada em breve.

Temos, então, um problema…

Os itens, a seguir, são algumas das dificuldades enfrentadas. Note que existem muitas outras dificuldades, fora as listadas abaixo. ;(

  • Diferenças entre o ambiente de desenvolvimento e de produção.
  • Portabilidade da aplicação.
  • Padronização do ambiente.

Felizmente, também temos uma solução:

O que é Docker?

Docker é uma plataforma aberta voltada para desenvolvedores e administradores de sistemas, que permite criar, enviar e executar aplicativos distribuídos, ou seja, aplicativos que “rodam” em laptops, VMs de data centers, servidores, ou até mesmo em nuvem.

Build, Ship, and Run Any App, Anywhere

Trazendo essa frase para o mundo dos containers, seria assim:

Crie, envie e execute containers em qualquer lugar

O que são containers?

Container é basicamente o chroot em uso, compartilhando o mesmo kerneldo host, onde é possível definir recursos como rede, memória, CPU e outros. Todo container Docker possui um identificador, que chamamos de CONTAINER ID. Containers Docker também podem possuir nomes, que são definidos no momento de sua criação.

Os containers Docker possuem a facilidade de serem criados, removidos e recriados, com base na mesma imagem, ou em uma imagem diferente.

Por que usar Docker e não Vagrant?

Porque o Vagrant “roda” em cima de uma VM e tem uma lentidão maior para execução, pois consome mais processos que um container comum, sendo difícil de ser replicado e transportado. Já os containers Docker são mais rápidos para iniciar e podem ser transportados com facilidade! Além disso, não necessitam do S.O. completo, possibilitando que você economize espaço no seu HD.

A primeira imagem demonstra como funciona uma VM e a segunda como funciona o Docker. Percebemos que a estrutura do docker é bem mais enxuta que a das VMs, pois não temos o Guest OS na estrutura do container e nem precisamos do S.O. completo para executar um ambiente separado: só precisamos do Kernel do Host OS. Isso faz com que o docker seja muito rápido e eficiente na hora de ser transportado de um lugar para o outro.

Não esqueça que a versão do Kernel precisa ser superior a 3.10.

Alguns comandos básicos do Docker são:

docker run - Inicia um novo container 
docker version - Mostra a versão instalada do Docker 
docker info - Mostra informações do sistema
docker images - Lista todas as imagens baixadas
docker ps - Lista todos os containers
docker exec - Executa um comando em um container em execução
docker inspect - Captura informações de um container ou uma imagem
docker kill - Finaliza um container em execução
docker rm - Remove um ou mais containers

Você pode conferir a lista completa de comandos usando o comando (docker help) ou através do linkhttps://docs.docker.com/engine/reference/commandline/

Trabalhando com Docker

Aqui está a lista de algumas coisas que precisamos entender para trabalhar com Docker.

  1. Sempre precisamos de uma imagem para criar um container, pois todocontainer é baseado em uma imagem.
  2. Sempre que criarmos um container, podemos expor uma porta onde será acessível no host, fazendo com que você tenha possibilidade de disponibilizar serviços para fora do container.
  3. Há possibilidade de entrar e sair do container, o que traz a facilidade de manipulação do mesmo para instalar libs, iniciar serviços, executar comandos e scripts, etc.
  4. Todo container dura enquanto seu processo estiver sendo executado; caso não inicie em modo interativo ou em background, ele será criado e removido rapidamente.
  5. É possível, de fora do container, executar comandos dentro dele, executarscripts, etc.

Instalação

Daqui pra frente assumimos que você já possui o docker instalado. Caso não possua, aqui está o link: https://docs.docker.com/engine/installation/

Estrutura de criação de um container

Antes de criarmos qualquer container, precisamos entender que os comandos possuem uma sequência lógica que irá definir a imagem e os argumentos que influenciarão na hora de executar o container. A seguir, vemos a estrutura de comandos para a criação de um container:

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

Hello World

Primeiramente, executamos o comando (docker run) e passamos qual imagem ele irá usar como base para criar o container:

docker run hello-world

Aqui está a saída:

pc-docker:~ alefcastelo$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete 
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.executar
To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com
For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

Ao criar um container e executar o comando (docker ps), você perceberá que não há nenhum container sendo executado. Isso acontece porque o containerfoi criado, mas logo depois ele foi removido.

Para criar um container e permitir que ele continue sendo executado, você pode colocar o argumento (-d) que faz com que o container seja executado em modo background. Outra opção é executar em modo interativo, usando o argumento (-i) acompanhado do (-t) para indicar que você quer executar comandos, além de ver a saída do container no seu terminal.

Criando um container para executar em background:

docker run -d IMAGE[:TAG|@DIGEST]
docker run -d php:5.6-apache

Para acessá-lo, você pode usar o comando (docker exec) acompanhado do argumento (-ti), que irá executar um comando dentro do container. Nesse caso, iremos acessar o bash:

docker exec -ti CONTAINER_ID /bin/bash

Após esse comando, temos total acesso ao nosso container.

Executando um container em modo interativo

Para executar um container em modo interativo, precisamos usar o argumento (-ti) e colocar qual comando queremos executar depois da imagem, conforme apresentado a seguir:

docker run -ti IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
docker run -ti php:5.6-apache /bin/bash

A partir desse momento, é possível instalar libs/bins para atender às necessidades da minha aplicação, fazendo com que seja desnecessário possuir um ambiente localmente instalado, além de evitar vários serviços sendo executados em paralelo.

Finalmente, para sair de um container, você deve pressionar as teclasCTRL+P+Q.

Usando imagens oficiais

Também é possível baixar imagens oficiais do PHP, MySQL, WordPress, Drupal, etc. Isso facilitará o seu trabalho na hora de criar containers com ambientes pré-configurados, sem que haja a necessidade de instalação de dependências.

Exemplo da criação de um container baseado em uma imagem oficial, no caso a do php:5.4:

pc-docker:~ alefcastelo$ docker run -ti php:5.4 /bin/bash
Unable to find image ‘php:5.4’ locally
5.4: Pulling from library/php
1a1bc86469d0: Pull complete 
Digest: sha256:6432eb062e481413223df92f86b2b93b2011a9f807d1461cb7ba38c2b646464a
Status: Downloaded newer image for php:5.4
root@3fb577e482d8:/# php -v
PHP 5.4.45 (cli) (built: Dec 5 2015 08:26:46) 
Copyright © 1997–2014 The PHP Group
Zend Engine v2.4.0, Copyright © 1998–2014 Zend Technologies

Usando Docker com PHP

Para iniciar uma aplicação PHP em um container, você pode entrar na pasta da aplicação e executar o comando:

docker run 
  -v $PWD:/var/www/html \
  -p 80:80 \
  -ti \
  php:5.6-apache \
  /bin/bash

Isso já é o suficiente pra você possuir uma aplicação PHP rodando dentro do seu container. Para visualizar essa aplicação em funcionamento, acesse olocalhost na porta 80.

Explicação do comando:

  1. Primeira linha define o comando Docker a ser executado.
  2. Segunda define o volume compartilhado entre o container e o Host OS.
  3. Terceira linha define a porta compartilhada.
  4. Quarta linha define que o container será executado em modo interativo.
  5. Quinta linha faz referência à imagem oficial do PHP.
  6. Enfim, a sexta linha diz qual comando será executado na inicialização docontainer.

Se você estiver usando uma imagem oficial do PHP e caso precise instalar novas dependências, diferentes da que já possui na imagem, use o comando que já foi inserido na imagem oficial. Exemplo:

docker-php-ext-install [EXTENSIONS...]
docker-php-ext-install pgsql 
docker-php-ext-install zip mysql gd

Esse comando fará com que sua extensão seja baixada e configurada no seu php.ini.

Continuarei esse conteúdo em um próximo post “Trabalhando em ambientes PHP com Docker[Parte-2]”Aguardem!!!

Abaixo postei uma foto para a galera de Fortaleza ver o quanto esse evento foi legal! Não deixe de ir para o próximo! 😉

Conteúdo retirado do blog: https://rumadecodigo.com.br/trabalhando-em-ambientes-php-com-docker-9515cf1153c2

Obrigado por enviar o seu comentário minha jóia!