O Docker é uma ferramenta Open Source que permite a criação de ambientes virtuais, utilizando para isso Linux Containers. Um container é um conjunto de processos isolados do restante do sistema, o que permite virtualização em nível de sistema operacional.

Com o Docker podemos criar pacotes que contenham não só a nossa aplicação, mas também todas as dependências necessárias para o seu funcionamento. Chamamos esses pacotes de images, e é a partir delas que o Docker constrói o container. Um container construído dessa forma se manterá consistente em diferentes etapas do desenvolvimento da aplicação, incluindo testes e implantação.

Podemos ainda versionar e distribuir images, juntamente com a configuração do ambiente de desenvolvimento utilizado para criá-la. Assim, trabalhar com images é algo próximo daquela que aplicamos ao código da aplicação. É possível, ainda, utilizar imagens prontas provenientes do Dockerhub para fazer em segundos tarefas de instalação e configuração de softwares, bibliotecas, dlls, enfim, tudo o que for necessário para que a aplicação funcione, algo que pode consumir muitas horas do programador com facilidade.

Virtualização: Máquina Virtual VS Docker Container

Antes de falar sobre o Docker precisamos entender o que é virtualização. Virtualizar é simular o comportamento físico de um computador por meio de um software. Antes desse conceito, precisávamos dedicar todos os recursos de um servidor a execução de uma única aplicação para garantir que ela funcionasse de forma isolada das demais. Hoje, a virtualização permite a execução de várias aplicações no mesmo servidor criando um isolamento lógico entre elas.

A primeira tecnologia utilizada para a virtualização de servidores foi a máquina virtual, também conhecidas como virtual machines ou, simplesmente, VMs. Nesse contexto, temos um software chamado Hypervisor, responsável pela execução das máquinas virtuais e pela distribuição dos recursos da máquina física entre elas. As máquinas virtuais, por sua vez, simulavam um servidor completo com seu próprio kernel e sistema operacional.

Representação do paradigma de servidor utilizando Máquinas Virtuais
Figura 1. Representação do paradigma de servidor utilizando Máquinas Virtuais

Embora tenha sido uma grande evolução em relação ao modelo anterior, a virtualização por meio de máquinas virtuais consome uma grande parte dos recursos do computador. Isso acontece pois o software Hypervisor precisa simular o funcionamento hardware do computador, criando uma ponte entre a máquina virtual e o hardware físico. Além disso, a máquina virtual possui o seu próprio kernel e sistema operacional, que também consomem recursos durante a sua execução.

Os containers linux, por outro lado, compartilham o Kernel do host (máquina física) em lugar de simular todos os componentes de um servidor físico. Assim, eles fornecem uma virtualização a nível de sistema operacional, o que isola as aplicações em execução sem utilizar tantos recursos da máquina quanto as máquinas virtuais.

Representação do paradigma de servidor utilizando Container
Figura 2. Representação do paradigma de servidor utilizando Container

Instalação e configuração do Docker

Windows

Para utilizar o Docker em uma máquina Windows:

  • Baixe o Docker para Windows e execute-o.
  • Siga o passo a passo do instalador. Você irá precisar aceitar os termos de uso, autorizar a instalação e esperar o Docker carregar todos os arquivos. Ao final, clique em Finish
  • Se não iniciar automaticamente, busque por "Docker" na barra de pesquisa do Windows e aperte dê um duplo clique sobre o ícone do Docker for Windows.

    Menu Windows
    Figura 1. Menu Windows

  • Faça login com sua conta do Docker. Se ainda não possui uma conta, acesse https://cloud.docker.com/ e crie gratuitamente.

    Tela de login do Docker
    Figura 2. Tela de login do Docker

  • Após realizar o login, vá na aba Settings e selecione todas as partições do seu HD e clique em Apply.

    Gerenciador do Docker
    Figura 3. Gerenciador do Docker

Linux

A instalação do Docker no Linux pode variar de acordo com a distribuição escolhida ou gerenciador de pacotes utilizado. Considerando que você esteja utilizando uma distribuição baseado no Debian, como Ubuntu, basta seguir os passos abaixo.

  • Atualize os índices de pacote do apt.
    $ sudo apt-get update
  • Instale os pacotes necessários para que o apt leia repositórios via HTTPS.
    $ sudo apt-get install 
        apt-transport-https 
        ca-certificates 
        curl 
        software-properties-common
  • Adicione a chave GPG oficial do Docker.
    $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

    Você pode confirmar se tudo ocorreu bem verificando se a saída do seguinte comando se parece com esta:
    $ sudo apt-key fingerprint 0EBFCD88
        pub 4096R/0EBFCD88 2017-02-22
        Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
        uid Docker Release (CE deb) <docker@docker.com>
        sub 4096R/F273FCD8 2017-02-22
  • Agora, adicione os repositório estável do Docker.
    $ sudo add-apt-repository 
        "deb [arch=amd64] https://download.docker.com/linux/ubuntu 
        $(lsb_release -cs) 
        stable"
  • Se tudo ocorreu bem até aqui, podemos executar o comando de instalação do Docker:
    $ sudo apt-get install docker-ce

Criando minha primeira Docker image

Todo container é gerado a partir de uma image (imagem). Por isso, para que possamos empacotar uma aplicação, devemos primeiro criar uma image (imagem) do ambiente no qual essa aplicação será executada. No diretório do nosso projeto, criaremos um arquivo index.php. Esse arquivo será a página inicial da nossa aplicação:

<?php
    phpinfo();
?>

Agora que temos criado o código que desejamos enviar para o container, podemos descrever em forma de instruções os passos que serão seguidos pelo Docker para construir a image. Por padrão, esse arquivo é chamado de Dockerfile e ficará localizado no diretório raiz do nosso projeto:

Diretório do projeto
Figura 3. Diretório do projeto

Construir uma imagem pode ser algo repetitivo, já que em muitos cenários diferentes os softwares necessários para que uma aplicação seja executada permanecerão os mesmos. O Dockerhub é um repositório oficial de imagens para o Docker, as quais podemos utilizar como ponto de partida para nossas próprias imagens. Sendo assim, construiremos uma imagem para esta aplicação utilizando uma image do PHP que já possui o Apache instalado e acrescentaremos a essa imagem alguns comandos para customizá-la, fazendo com que se adeque as nossas necessidades.

FROM php:7.1-apache
COPY ./ /var/www/html
EXPOSE 80
CMD ["apache2-foreground"] 
  • Linha 1: a cláusula FROM é obrigatória e indica qual é a imagem inicial utilizada.
    FROM php:7.1-apache
  • Linha 2: o comando COPY permite que enviemos arquivos do Host para o container. No nosso exemplo, estamos enviando todos os arquivos da raiz do projeto (inclusive o index.php) para o diretório público do Apache.
    COPY ./ /var/www/html
  • Linha 3: com o comando EXPOSE podemos indica em qual porta o container estará funcionando. Esse comando não libera a porta para Host, isso é feito pelo parâmetro -p do comando docker run . Dessa forma, utilizamos o comando EXPOSE como um indicativo de quais portas devem ser liberadas.
    EXPOSE 80
  • Linha 4: a cláusula CMD é obrigatória, e deve estar sempre ao final do Dockerfile. Esse instrução contém o comando que será executado assim que o contêiner iniciar a sua execução. Nesse contexto, apache2-foreground inicia a execução do servidor HTTP apache.
    CMD ["apache2-foreground"]

Com todos os arquivos criados, podemos navegar no console até o diretório do nosso projeto e executar o comando:

docker build -t minha_image .

A opção -t permite nomear nossa image. Nesse caso, demos o nome de minha_image.

O Docker deve executar todos os comandos e baixar a imagem inicial. Ao final da execução, você deve ver algo similar a isso:

Sending build context to Docker daemon 3.072kB
        Step 1/4 : FROM php:7.1-apache
        ---> dab2c21710c3
        Step 2/4 : COPY ./ /var/www/html
        ---> Using cache
        ---> c41c0baea8f8
        Step 3/4 : EXPOSE 80
        ---> Using cache
        ---> 334435d4b263
        Step 4/4 : CMD ["apache2-foreground"]
        ---> Using cache
        ---> cf4cbd043000
        Successfully built cf4cbd043000
        Successfully tagged minha_image:latest
        

Iniciando nosso container com o comando docker run

Nossa imagem foi criada e estamos prontos para iniciar nosso container, para isso utilizaremos o comando docker run:

docker run -p 80:80 -d minha_image

Note nesse momento que a porta informada, 80, é a mesma que configuramos na instrução EXPOSE.

  • Com o parâmetro -p podemos indicar qual porta do Host será utilizada para acessar a porta do Container
  • O -d fará com que o nosso container seja executado em Background.

Agora nosso primeiro container está funcionando e já podemos testá-lo. Para isso, basta abrir o navegador e acessar http://localhost:80 ou simplesmente http://localhost, pois 80 é a porta HTTP padrão.

Testando a aplicação
Figura 4. Testando a aplicação

Criamos nosso primeiro Docker container utilizando uma imagem pronta do Dockerhub e fizemos as modificações necessárias para que nossa aplicação pudesse funcionar.

As ferramentas utilizadas no desenvolvimento de aplicações tem evoluído muito rápido, e essas aplicações estão cada dia mais complexas. O Docker possibilita que a infraestrutura acompanhe essa evolução, tornando as tarefas de criar, publicar e escalar aplicações algo simples e cotidiano.

Para continuar aprendendo sobre o Docker com exemplos práticos assista a série Navegando com o Docker. Confira!

Confira também