Primeiros Passos com Docker: Conceitos Básicos à Criação de sua Primeira Imagem
Nos últimos tempos você já deve ter ouvido falar de Docker, de containers ou acabou se deparando com um arquivinho sem vergonha chamado Dockerfile na raiz do seu projeto. Mas o que tudo isso significa e como funciona?
Docker é uma plataforma voltada para a criação e execução de containers. Diferente de uma VM, um container empacota somente o código, dependências e variáveis de ambiente necessárias para a execução de uma aplicação. Sendo assim, ao invés de termos uma infraestrutura onde cada VM tem seu próprio SO sendo responsável por uma aplicação diferente, temos uma infraestrutura onde, com apenas um sistema operacional e através do Docker, podemos gerenciar diversas aplicações. Cada uma dessas aplicações é executada de forma isolada, sem a necessidade de um sistema operacional próprio.
Para um container ser criado, ele necessita de uma imagem: o básico para a aplicação ser executada, desde bibliotecas até variáveis de ambiente. Essas imagens são criadas através de um Dockerfile e podem ser baixadas e publicadas em diversos registries, sendo o mais famoso deles o Docker Hub. A imagem abaixo nos mostra um resumo do fluxo da estrutura do Docker e de como esses componentes se relacionam entre si.
Meio confuso, né? Para entender melhor como esse fluxo funciona, vamos começar com um pouco de prática, seguindo alguns passos:
1. Instalar o Docker
A instalação para distribuições Linux pode ser feita aqui. Uma vez feito o download, basta conferir a versão com o seguinte comando:
docker --version
2. Fazendo download de imagens
Para fazer o download de uma imagem, usamos o comando docker pull, passando como argumento o nome da imagem que queremos baixar. Essas imagens são baixadas de um registry, que funciona como plataforma de compartilhamento dessas mesmas imagens. Uma vez cadastrado no registry, o usuário pode fazer download e alterar essas mesmas imagens conforme sua necessidade.
Nesse exemplo, vamos utilizar o registry padrão do Docker, o DockerHub. Cada imagem nessa plataforma é identificada da seguinte forma:
nome-do-usuario/nome-da-imagem
Todavia, imagens oficiais não seguem esse padrão, sendo identificadas apenas pelo seu nome. Se pesquisarmos por “node”, encontraremos mais de 50 mil resultados, sendo o primeiro deles a imagem oficial:
Se irmos um pouco mais abaixo na listagem, poderemos ver outra imagem do Node pertencente ao usuário nodejsn, sendo identificado seu nome antes do nome da própria imagem:
Se acessarmos a página da imagem oficial do Node, encontraremos o comando para fazer download da imagem:
Mas o que de fato vai acontecer se eu rodar esse comando?
Ao receber o comando pull sem uma versão específica, o docker client pede para docker daemon verificar se já temos a versão mais recente da imagem em nossa máquina. Se a imagem não existir no repositório local(nosso caso), ele vai buscar em seu registry padrão pelo nome que passamos por parâmetro e então, se existir uma imagem com o nome passado, irá realizar o download nos fornecendo a seguinte saída:
3. Criando imagens
Através de um Dockerfile, podemos criar uma nova imagem usando outra como base. Também é possível especificar uma série de comandos para criar estruturas específicas para o deploy de nossas aplicações. O arquivo abaixo é um exemplo de Dockerfile para uma aplicação básica escrita em JavaScript.
Cada um dos comandos acima exerce uma função diferente:
- FROM especifica a imagem base que será usada;
- ENV declara uma variável de ambiente;
- RUN executa um comando;
- WORKDIR muda o diretório atual(similar ao comando cd em um terminal);
- COPY copia arquivos e diretórios do host para o build da imagem(sendo o segundo argumento o nome que será usado no build);
- EXPOSE expõe uma porta qualquer;
- CMD indica o comando que será rodado para iniciar a aplicação em um container construído usando essa imagem.
Usando o arquivo acima conseguiremos ver o processo em ação. Basta copiar para um diretório de sua escolha e nomeá-lo para index.js. Feito isso, rodaremos o seguinte comando:
docker image build -t node-app .
Com o comando acima estamos indicando para o docker construir uma imagem utilizando uma tag para identificá-la como a última versão criada da imagem node-app e dizendo que o Dockerfile necessário para construir a imagem está no diretório atual. Após esse comando ser executado, poderemos montar um container usando a imagem gerada.
4. Usando uma imagem para executar um container
Tendo nosso Dockerfile criado e nossa imagem criada, basta executar o comando abaixo para a mágica acontecer:
docker container run -d -p 80:8080 node-app
Com esse comando, estamos basicamente dizendo ao Docker “crie um container(docker container run) que rode no background, sem ocupar meu terminal atual(-d), mapeando uma porta local para uma outra exposta no container(-p 80:8080) e usando a imagem node-app”. Caso a imagem não exista, o docker daemon fará uma busca pelo nome em algum registry.
Agora basta seguir a documentação do Docker para aprender muitas outras possibilidades para montar imagens e configurar containers. Por fim, não se esqueçam de acessar o localhost e ver o resultado dos quatro passos que seguimos ao longo desse artigo.