DevOps & CI/CD Nathan Geeksman

Docker para Iniciantes: Conceitos de Containers e Imagens.

Docker para Iniciantes: Conceitos de Containers e Imagens.

Docker para Iniciantes: Conceitos de Containers e Imagens.

Introdução

O desenvolvimento de software está em constante evolução, e uma das tendências mais significativas nos últimos anos é a adoção de tecnologias de containerização. O Docker é um dos principais players nesse campo, oferecendo ferramentas para criar, compartilhar e executar containers de aplicativos. Em um cenário em que a complexidade cresce exponencialmente, a necessidade de isolamento e reprodutibilidade de ambientes de desenvolvimento e produção se tornou crítica.

Nesse contexto, entender os conceitos básicos de containers e imagens é fundamental para qualquer profissional envolvido no processo de desenvolvimento de software. O objetivo desse artigo é apresentar esses conceitos de forma clara e objetiva, fornecendo uma base sólida para que você possa explorar as funcionalidades do Docker com confiança.

Ao final dessa seção introdutória, você terá um entendimento básico sobre:

  • O que são containers e imagens no contexto de desenvolvimento de software
  • Por que a utilização desses conceitos é essencial para garantir a reprodutibilidade dos ambientes de desenvolvimento e produção

Seja bem-vindo à exploração das funcionalidades do Docker.

O que é e por que importa

Containers

Um container é uma unidade de isolamento que permite executar um aplicativo com suas próprias dependências, em vez de compartilhar o ambiente do host. Isso significa que cada container tem seu próprio espaço alocado no sistema operacional, onde podem ser executadas e gerenciadas sem influenciar outros containers ou o sistema host.

Os contêineres são criados a partir da execução de uma imagem, que é um modelo pré-configurado de ambiente com todas as dependências necessárias para que o aplicativo seja executado. Isso é feito utilizando o comando docker run, que inicializa um novo contêiner de acordo com as instruções presentes na imagem utilizada.

Imagens

Uma imagem é um modelo pré-configurado de ambiente isolado, que inclui todas as dependências necessárias para executar um aplicativo. Isso pode ser comparado a uma "sopa pronta" do ambiente de desenvolvimento, pois contém tudo o que é necessário para o funcionamento correto do software.

As imagens são criadas utilizando o comando docker build, que lê os Dockerfile, instruções que descrevem como criar a imagem. A partir das instruções presentes no Dockerfile, é possível construir imagens personalizadas de acordo com as necessidades específicas do aplicativo.

O uso de imagens oferece várias vantagens, incluindo:

  • Isolamento dos ambientes: As imagens permitem que os desenvolvedores criem ambientes isolados para cada projeto, garantindo que nenhuma alteração feita em um projeto afete outro.
  • Reutilização de configurações: Uma vez construída uma imagem, ela pode ser reutilizada várias vezes sem necessidade de reconfiguração.
  • Simplificação da migração: Com as imagens, é fácil migrar aplicativos entre diferentes ambientes, seja para desenvolvimento ou produção.

Essas características são fundamentais para garantir a reprodutibilidade dos ambientes, uma das principais motivações por trás do uso de containers e imagens. Ao usar esses conceitos, os desenvolvedores podem criar ambientes replicáveis e consistentes, o que facilita a colaboração entre equipes e reduz o tempo necessário para solucionar problemas.

Essencialmente, a combinação de imagens e contêineres permite aos desenvolvedores trabalhar com confiança em ambientes controlados e replicáveis, tornando mais eficientes e produtivos no processo de desenvolvimento.

Como funciona na prática

O funcionamento interno dos contêineres e imagens pode ser compreendido em várias etapas:

  • Etapas do Ciclo de Vida de um Contêiner:
  • Criação: Um contêiner é criado a partir de uma imagem existente.
  • Execução: O contêiner começa a rodar e o sistema operacional em execução dentro dele é iniciado.
  • Parada: O contêiner pode ser parado, mas ainda existe na memória.
  • Exclusão: O contêiner é excluído da lista de processos ativos e todos os arquivos associados a ele são apagados.
  • Processo de Criação de uma Imagem:
  • O usuário inicia o processo de criação de uma imagem utilizando o comando docker build.
  • Esse comando lê as instruções do arquivo Dockerfile e executa-as sequencialmente.
  • A partir dessas instruções, a imagem é criada com todas as configurações necessárias para o funcionamento correto do aplicativo.
  • Execução de um Contêiner a Partir de uma Imagem:
  • O usuário executa o comando docker run, especificando a imagem que deseja usar.
  • O Docker lê as instruções do arquivo Dockerfile associado àquela imagem e cria um novo contêiner com todas as configurações definidas no arquivo.
  • Vantagens da Isolamento:
  • O uso de contêineres oferece uma camada adicional de isolamento entre aplicativos, garantindo que cada programa roda em seu próprio ambiente virtual.
  • Dessa forma, as alterações feitas em um projeto não afetam outros projetos e vice-versa.

Exemplo real

Um exemplo prático pode ser feito criando uma imagem e um contêiner para rodar um simples aplicativo web.

FROM ubuntu:latest

RUN apt-get update && apt-get install -y apache2

COPY index.html /var/www/html/

EXPOSE 80

CMD ["service", "apache2", "start"]
// Comando para criar a imagem com base no arquivo Dockerfile
docker build -t meu-aplicativo .

// Comando para executar um contêiner da imagem criada anteriormente, exposto na porta 8080 do sistema host
docker run -p 8080:80 meu-aplicativo

// Navegue para http://localhost:8080/ no navegador para acessar a página web

Nesse exemplo, após rodar o comando docker build, uma imagem chamada meu-aplicativo é criada. Em seguida, ao executar docker run -p 8080:80 meu-aplicativo, um contêiner novo é iniciado com base naquela imagem e expondo a porta 80 do sistema host através da porta 8080. Para acessar a página web, basta abrir o navegador e digitar http://localhost:8080/.

Boas práticas

Manter a imagem atualizada: mantenha as imagens atualizadas para evitar vulnerabilidades de segurança conhecidas.

Utilizar volumes para persistir dados: use volumes para armazenar dados persistentes em vez de dentro do contêiner, pois isso permite que os dados sobrevivam à execução ou encerramento do contêiner.

Desenvolver scripts de build confiáveis: escreva scripts de build robustos e testados para garantir que a imagem seja construída corretamente.

Utilizar variáveis de ambiente: use variáveis de ambiente para configurar os aplicativos em vez de hardcoding as configurações.

Armadilhas comuns

  • Imagens pesadas: as imagens podem crescer rapidamente, o que pode causar problemas de armazenamento e carregar tempos de inicialização. Use multi-stage builds ou Docker Slim para reduzir o tamanho das imagens.
  • Falha ao lidar com dependências transientes: se os contêineres forem criados em uma rede diferente daquela onde ele irá rodar, as dependerencias não estarão resolvidas corretamente. Isso pode causar problemas de build e execução do aplicativo.
  • Exposição de portas inadequada: ao expor muitas portas em um contêiner, você permite que ataques de força bruta possam ser usados contra as aplicações. Isso também pode levar a problemas de segurança relacionados à gestão de credenciais.
  • Imagem não reutilizável: se uma imagem não for baseada em outra imagem, ela não poderá aproveitar os benefícios de uma image já existente.

Conclusão

Os conceitos de containers e imagens são fundamentais para entender como Docker funciona. É importante lembrar que as imagens devem ser mantidas atualizadas, os volumes utilizados para persistir dados, e scripts de build confiáveis desenvolvidos.

Para evitar problemas comuns, é recomendável verificar se a imagem não está pesada, lidando corretamente com dependências transientes e expor portas apenas quando necessário. Além disso, é crucial garantir que as imagens sejam reutilizáveis, baseadas em outras imagens existentes.

Se você está começando a trabalhar com Docker, sugere-se ler sobre como criar imagens e contêineres personalizados, além de aprender sobre networking em containers. Aprofundar seus conhecimentos em segurança, armazenamento e gerenciamento de imagens também é essencial para aproveitar ao máximo as funcionalidades do Docker.

Referências

  • Docker. Dockerfile reference. Disponível em: https://docs.docker.com/engine/reference/builder/. Acesso: 2024.
  • MDN Web Docs. Containers and containerization. Disponível em: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Containerization. Acesso: 2024.
  • Martin Fowler. Container Management. Disponível em: https://martinfowler.com/articles/container-management.html. Acesso: 2024.
  • OWASP. Docker Security Considerations. Disponível em: https://owasp.org/www-project-docker-security/. Acesso: 2024.
  • Thoughtworks. Using Docker for Development and Testing. Disponível em: https://www.thoughtworks.com/insights/blog/using-docker-development-and-testing. Acesso: 2024.